Dialogues Multi-Agents Argumentatifs

Navigation: ← Tweety-7b-Ranking-Probabilistic | Index | Tweety-9-Préférences →


Objectifs pédagogiques

  1. Comprendre le framework d’agents de TweetyProject
  2. Découvrir les protocoles de dialogue argumentatif
  3. Simuler des débats entre agents avec échanges structurés
  4. Explorer les stratégies argumentatives et la résolution de conflits

Prérequis

Exécutez d’abord Tweety-01-Setup-Python.ipynb pour configurer l’environnement JVM.

Durée estimée : 35 minutes

Modules TweetyProject couverts

  • 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 = False

import jpype
import jpype.imports
import os
import pathlib
import shutil
import 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, "")
    if not path_str:
        return None
    if shutil.which(path_str):
        return path_str
    path_obj = pathlib.Path(path_str)
    if path_obj.is_file():
        return str(path_obj.resolve())
    if path_obj.is_dir():
        return str(path_obj.resolve())
    return None

# --- Auto-detection des outils ---
system = platform.system()
exe_suffix = ".exe" if system == "Windows" else ""

# 1. Clingo (ASP solver) - Tweety attend le REPERTOIRE
for 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 if isinstance(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()) if isinstance(sp, pathlib.Path) else sp
        break

# 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) if isinstance(ep, str) else ep
        if 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 = True
else:
    jdk_portable = None
    for 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}")
                break

    if not os.environ.get("JAVA_HOME"):
        print("ERREUR: JAVA_HOME non defini et JDK portable non trouve.")
    else:
        LIB_DIR = pathlib.Path("libs")
        if not 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 = True
                except Exception as 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] if len(path) > 30 else path
            print(f"  {tool}: {short_path}")
    print(f"\nJVM prete. Outils: {sum(1 for t,p in EXTERNAL_TOOLS.items() if p)}/{len(EXTERNAL_TOOLS)}")
--- Verification JVM Tweety + Outils ---
JDK portable: zulu17.50.19-ca-jdk17.0.11-win_x64
JVM demarree avec 42 JARs.

--- Outils disponibles ---
  EPROVER: eprover.exe
  SAT_SOLVER_PYTHON: sat_solver.py
  MARCO: marco.py

JVM prete. Outils: 3/5

Interprétation de la configuration

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 ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Exploration des dialogues argumentatifs...")
    dialogues_imports_ok = False
    try:
        import jpype
        from jpype.types import *
        
        # Imports dialogues
        try:
            from org.tweetyproject.agents.dialogues import ExecutableExtension
            print("Import ExecutableExtension reussi.")
            dialogues_imports_ok = True
        except ImportError as e:
            print(f"Import direct ExecutableExtension echoue: {e}")
        
        # Exploration du package dialogues et ses sous-packages
        print("\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}")
                except Exception:
                    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 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.
""")

    except Exception as 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 ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Exploration des jeux de loterie...")
    try:
        import jpype
        from jpype.types import *
        
        # Imports nécessaires
        from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attack
        from org.tweetyproject.arg.dung.semantics import Semantics
        from org.tweetyproject.arg.prob.lotteries import SubgraphProbabilityFunction, ArgumentationLottery, UtilityFunction
        from org.tweetyproject.arg.dung.divisions import Division
        from org.tweetyproject.arg.dung.semantics import Extension
        
        print("Imports pour loteries reussis.")
        
        # Créer un framework simple
        print("\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_SEMANTICS
        try:
            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
""")
        except Exception as e_prob:
            print(f"Erreur calcul probabilites: {e_prob}")
        
    except ImportError as e:
        print(f"Erreur d'import pour loteries: {e}")
    except jpype.JException as e_java:
        print(f"Erreur Java: {e_java.message()}")
    except Exception as 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. Proteger evidence_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:

Composant Description Classes TweetyProject
Agents de base Abstraction d’agents autonomes Agent, DummyAgent, MultiAgentSystem
Dialogues Protocoles d’échange structurés DialogueTrace, ExecutableExtension
Loteries Argumentation probabiliste + décision AbstractLotteryAgent, LotteryGameSystem

Architecture d’un dialogue argumentatif

Agent A                    Agent B
   |                          |
   |------ ASSERT(arg1) ----->|
   |                          |
   |<----- CHALLENGE(arg1) ---|
   |                          |
   |------ ASSERT(arg2) ----->|  (défense de arg1)
   |                          |
   |<----- ACCEPT / ATTACK ---|
   |                          |
         ... (tours suivants)

Points clés

  1. MultiAgentSystem gère l’interaction entre plusieurs agents
  2. Les protocoles définissent les règles du dialogue (moves autorisés, tours, terminaison)
  3. Les loteries permettent la prise de décision rationnelle quand l’issue est incertaine
  4. L’acceptabilité probabiliste guide les stratégies des agents

Limitations

  • Le module agents.dialogues est conçu pour être étendu avec des classes concrètes
  • L’implémentation complète nécessite de définir des protocoles spécifiques
  • Les exemples Java de TweetyProject fournissent des implémentations de référence

Prochaines étapes

Le notebook suivant explore le module Préférences pour l’agrégation de préférences et la théorie du vote.


Navigation: ← Tweety-7b-Ranking-Probabilistic | Index | Tweety-9-Préférences →

Exemple guide : Simulation de Dialogue Multi-Agents

Créez un scénario de negociation entre agents avec des positions opposees.

Objectifs

  1. Modeliser un conflit entre 3 agents (acheteur, vendeur, mediateur)
  2. Définir les croyances initiales de chaque agent
  3. Simuler un dialogue avec echanges d’arguments
  4. 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.

if not jvm_ready:
    print("JVM non demarree. Re-executer la cellule 1.")
else:
    from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attack
    from org.tweetyproject.arg.dung.semantics import Semantics
    from org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasoner
    from 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_SEMANTICS
    print("\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 publique

if not jvm_ready:
    print("JVM non demarree. Re-executer la cellule 1.")
else:
    from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attack
    from org.tweetyproject.arg.dung.semantics import Semantics
    from org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasoner
    from 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 argument
    print(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_SEMANTICS
    print("\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 in zip(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 3
print("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)
  • outils : “Les outils collaboratifs reduisent l’isolement” (PRO, attaque isolement)

Indices :

  • 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-graphe

if not 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

  1. Charger GroundedGameSystem via jpype.JClass
  2. Lister les méthodes publiques (introspection)
  3. Verifier le vainqueur théorique avec SimpleGroundedReasoner

Indices :

  • GroundedGameSystem = jpype.JClass("org.tweetyproject.agents.dialogues.oppmodels.GroundedGameSystem")
  • 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 comparer

if not 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 GroundedGameSystem
    print("Exercice a completer")
Exercice a completer
Retour au sommet