Frameworks d’Argumentation Étendus

Navigation: ← Tweety-6-Structured-Argumentation | Index | Tweety-7b-Ranking-Probabilistic →


Objectifs pédagogiques

  1. Découvrir les Abstract Dialectical Frameworks (ADF) et leurs conditions d’acceptation
  2. Maîtriser les frameworks bipolaires (Evidential, Necessity)
  3. Explorer les frameworks pondérés (WAF) et sociaux (SAF)
  4. Comprendre les Set Argumentation Frameworks (attaques collectives)
  5. Appréhender les frameworks étendus avec attaques sur attaques (EAF/REAF)

Prérequis

Ce notebook utilise le module partagé tweety_init.py pour l’initialisation JVM.

Durée estimée : 50 minutes

Note technique : Les solveurs SAT natifs (NativeMinisatSolver, NativeLingelingSolver, NativePicosatSolver) sont automatiquement chargés grâce au dossier libs/native/ configuré dans le classpath.

# --- Initialisation JVM Tweety via module partagé ---
from tweety_init import init_tweety, EXTERNAL_TOOLS, get_tool_path, print_tools_summary

jvm_ready = init_tweety()
print_tools_summary()
--- Initialisation Tweety ---
JDK portable: zulu17.50.19-ca-jdk17.0.11-win_x64
Bibliotheques natives: native/
JVM demarree avec 42 JARs.

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

Outils: 5/5

Structure du notebook

Ce notebook est organisé en 5 parties complémentaires:

  1. ADF (Abstract Dialectical Frameworks) : Conditions d’acceptation flexibles avec formules propositionnelles
  2. Frameworks Bipolaires : Introduction des relations de support (Evidential vs Necessity)
  3. Frameworks Pondérés (WAF) : Poids sur les attaques avec seuils de tolérance
  4. Frameworks Sociaux (SAF) : Votes positifs/négatifs et propagation de scores
  5. Attaques collectives et récursives : SetAF (ensembles attaquants) et EAF/REAF (meta-attaques)

Chaque section illustre une extension différente des cadres de Dung classiques, avec des applications pratiques variées.

Partie 5a : Frameworks d’Argumentation Étendus

Cette section explore des extensions complexes des cadres de Dung, permettant de modéliser des scénarios de raisonnement plus riches avec des conditions d’acceptation spécifiques, des relations de support, des poids, et des attaques collectives ou récursives.

5.1 Abstract Dialectical Frameworks (ADF)

Les ADF [Brewka & Woltran, 2010] généralisent les cadres de Dung.

Origine. Les Abstract Dialectical Frameworks (ADF) sont introduits par Brewka, G. & Woltran, S. (2010), Abstract dialectical frameworks, Proceedings of KR 2010, pp. 102-111 — qui généralisent les cadres de Dung en remplaçant les attaques binaires par une condition d’acceptation propositionnelle par argument (les formulations de 2013 et ultérieures en sont des extensions). Au lieu d’attaques binaires, chaque argument (ou statement) porte une condition d’acceptation : une formule propositionnelle sur ses parents. Les sémantiques ADF sont trivaluées : chaque statement reçoit la valeur t (vrai/accepté), f (faux/rejeté) ou u (indécis / undecided). Tweety classe en outre chaque lien parent → statement selon sa nature — attaquant, supportant, dépendant (les deux selon le contexte) ou redondant — ce qui est précisément ce qui généralise Dung : un lien purement attaquant correspond à une attaque de Dung, tandis que les liens supportants et dépendants ajoutent une expressivité que Dung n’a pas.

Sémantiques : Admissible, Complete, Grounded, Preferred, Stable (toutes trivaluées) Module Tweety : arg.adf — les types de liens sont calculés par SatLinkStrategy, qui teste via un solveur SAT, pour chaque parent, s’il peut faire basculer la valeur de la condition d’acceptation

IMPORTANT - Solveurs SAT Natifs: Le raisonnement ADF nécessite un solveur SAT incrémental natif. TweetyProject supporte MiniSat, Lingeling, et PicoSAT via JNI.

Prérequis : Les bibliothèques natives doivent être dans java.library.path : - Windows : minisat.dll, lingeling.dll, picosat.dll - Linux : minisat.so, lingeling.so, picosat.so

Ces fichiers sont fournis dans libs/native/ et automatiquement chargés si Tweety-1-Setup est exécuté.

# --- 5.1 Abstract Dialectical Frameworks (ADF) ---
print("\n--- 5.1 Abstract Dialectical Frameworks (ADF) ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple ADF...")
    print("\n=== Test des solveurs SAT natifs ===")
    
    # Verifier si java.library.path inclut les libs natives
    try:
        import jpype
        java_lib_path = jpype.java.lang.System.getProperty("java.library.path")
        print(f"java.library.path: {java_lib_path[:100]}..." if len(java_lib_path) > 100 else f"java.library.path: {java_lib_path}")
    except:
        print("Impossible de lire java.library.path")

    adf_imports_ok = False
    native_solver_available = False
    native_solver_name = None
    
    try:
        from jpype.types import *
        from java.io import File
        from java.util import Collection

        from org.tweetyproject.arg.adf.syntax.adf import AbstractDialecticalFramework
        from org.tweetyproject.arg.adf.syntax import Argument as AdfArgument
        from org.tweetyproject.arg.adf.syntax.acc import AcceptanceCondition, NegationAcceptanceCondition
        from org.tweetyproject.arg.adf.io import KppADFFormatParser
        from org.tweetyproject.arg.adf.semantics.link import SatLinkStrategy, LinkStrategy
        from org.tweetyproject.arg.adf.semantics.interpretation import Interpretation
        from org.tweetyproject.arg.adf.reasoner import AdmissibleReasoner, CompleteReasoner, GroundReasoner
        from org.tweetyproject.logics.pl.sat import Sat4jSolver
        from org.tweetyproject.arg.adf.sat import IncrementalSatSolver

        print("Imports ADF de base reussis.")
        adf_imports_ok = True

        # Tenter de charger les solveurs natifs dans l'ordre de preference
        adf_solver = None
        solvers_to_try = [
            ("NativeMinisatSolver", "org.tweetyproject.arg.adf.sat.solver.NativeMinisatSolver"),
            ("NativeLingelingSolver", "org.tweetyproject.arg.adf.sat.solver.NativeLingelingSolver"),
            ("NativePicosatSolver", "org.tweetyproject.arg.adf.sat.solver.NativePicosatSolver"),
        ]
        
        print("\nTentative de chargement des solveurs SAT natifs:")
        for solver_name, solver_class_name in solvers_to_try:
            try:
                SolverClass = jpype.JClass(solver_class_name)
                adf_solver = SolverClass()
                native_solver_available = True
                native_solver_name = solver_name
                print(f"  OK {solver_name} charge avec succes!")
                break
            except jpype.JException as e_java:
                err_msg = str(e_java.message()) if hasattr(e_java, 'message') else str(e_java)
                if "UnsatisfiedLinkError" in err_msg or "no " in err_msg.lower():
                    print(f"  -- {solver_name}: DLL/SO non trouve (java.library.path)")
                else:
                    print(f"  -- {solver_name}: {err_msg[:60]}...")
            except Exception as e:
                print(f"  -- {solver_name}: {e}")
        
        if not native_solver_available:
            print("\nAucun solveur SAT natif disponible.")
            print("   Les DLLs (minisat.dll, lingeling.dll, picosat.dll) doivent etre")
            print("   dans java.library.path. Verifiez que Tweety-1-Setup a configure NATIVE_LIBS_DIR.")
            print("\n   Fallback vers Sat4jSolver (NON incremental)...")
            adf_solver = Sat4jSolver()

        print(f"\nSolveur selectionne: {adf_solver.getClass().getSimpleName()}")
        
        # Tester si le solveur est incremental
        IncrementalSatSolver_class = jpype.JClass("org.tweetyproject.arg.adf.sat.IncrementalSatSolver")
        is_incremental = isinstance(adf_solver, IncrementalSatSolver_class)
        print(f"Est incremental: {is_incremental}")
        
        if is_incremental:
            print("\n=== Test ADF avec solveur incremental ===")
            link_strategy = SatLinkStrategy(adf_solver)
            print("SatLinkStrategy creee avec succes.")
            
            # Arguments ADF - note: Argument implemente AcceptanceCondition
            a = AdfArgument("a")
            b = AdfArgument("b")
            c = AdfArgument("c")
            
            # ADF: a accepte si non-b, b accepte si non-c, c toujours accepte
            # NegationAcceptanceCondition prend un AcceptanceCondition (Argument en est un)
            builder = AbstractDialecticalFramework.builder()
            builder.add(a, NegationAcceptanceCondition(b))  # a accepte si NOT b
            builder.add(b, NegationAcceptanceCondition(c))  # b accepte si NOT c
            builder.add(c, AcceptanceCondition.TAUTOLOGY)   # c toujours accepte
            
            adf = builder.lazy(link_strategy).build()
            print(f"\nADF cree avec {adf.size()} arguments:")
            for arg in adf.getArguments():
                acc = adf.getAcceptanceCondition(arg)
                print(f"  {arg}: {acc}")
            
            # Raisonnement
            print("\nCalcul des extensions:")
            try:
                grounded_reasoner = GroundReasoner(adf_solver)
                grounded = grounded_reasoner.getModel(adf)
                print(f"  Grounded: {grounded}")
            except Exception as e:
                print(f"  Erreur calcul Grounded: {e}")
                
            print("\nOK Test ADF avec solveur SAT natif reussi!")
        else:
            print("\nCONCLUSION: Le raisonnement ADF necessite un solveur SAT incremental natif.")
            print("   Sat4jSolver n'est pas incremental, donc ADF ne peut pas fonctionner.")
            print("   Solution: Assurez-vous que NATIVE_LIBS_DIR est configure dans Tweety-1-Setup")
            print("   et que la JVM est redemarree apres modification.")

    except ImportError as e:
        print(f"Erreur d'import pour ADF : {e}. Verifiez le JAR 'arg.adf'.")
    except jpype.JException as e_java:
        print(f"Erreur Java generale: {e_java.message()}")
        print(e_java.stacktrace())
    except Exception as e_gen:
        print(f"Erreur Python inattendue: {e_gen}")
        import traceback
        traceback.print_exc()

--- 5.1 Abstract Dialectical Frameworks (ADF) ---
JVM prete. Execution de l'exemple ADF...

=== Test des solveurs SAT natifs ===
java.library.path: <repo>MyIA.AI.Notebooks\SymbolicAI\Argument_Analysis\libs\native
Imports ADF de base reussis.

Tentative de chargement des solveurs SAT natifs:
  OK NativeMinisatSolver charge avec succes!

Solveur selectionne: NativeMinisatSolver
Est incremental: True

=== Test ADF avec solveur incremental ===
SatLinkStrategy creee avec succes.

ADF cree avec 3 arguments:
  a: neg(b)
  c: T
  b: neg(c)

Calcul des extensions:
  Grounded: {t(a) t(c) f(b)}

OK Test ADF avec solveur SAT natif reussi!

Exemple pratique : ADF avec conditions d’acceptation

L’exemple suivant crée un ADF simple avec 3 arguments et des conditions de négation. Le code vérifie également la disponibilité des solveurs SAT natifs, qui sont essentiels pour le fonctionnement des ADF.

Objectif : Démontrer que les ADF peuvent exprimer des conditions plus complexes qu’un simple graphe d’attaques.

Interpretation des résultats ADF

L’ADF créé modelise une chaîne de dependances negatives :

c (toujours accepte) --[nie]--> b --[nie]--> a

Conditions d’acceptation : - c: T (tautologie) : c est inconditionellement accepte - b: neg(c) : b est accepte si et seulement si c est rejete - a: neg(b) : a est accepte si et seulement si b est rejete

Extension Grounded (trivaluee) : {t(a) t(c) f(b)}

La sémantique grounded d’un ADF est trivaluee : chaque statement recoit t (vrai/accepte), f (faux/rejete) ou u (indecis). C’est le plus petit point fixe de l’opérateur caractéristique. Ici la chaîne de conditions est déterministe, donc aucun statement ne reste u ; sur des conditions cycliques (ex. a: neg(a)), grounded affecterait la valeur u.

Argument Statut Explication
c t (true/accepte) Condition = T, donc toujours vrai
b f (false/rejete) Condition = neg(c), mais c=t, donc b=f
a t (true/accepte) Condition = neg(b), et b=f, donc a=t

Différence avec Dung - les types de liens : Dans un framework de Dung classique, on aurait défini des attaques c -> b et b -> a. L’ADF remplace les attaques binaires par des conditions d’acceptation, et classe chaque lien parent -> statement selon sa nature, calculee ici par SatLinkStrategy : - attaquant : rendre le parent vrai tend a rendre la condition fausse (ici neg(c) rend le lien c -> b attaquant) ; - supportant : rendre le parent vrai tend a rendre la condition vraie ; - dependant : le parent peut etre attaquant ou supportant selon la valeur des autres parents ; - redondant : le parent n’influence pas la condition.

Un ADF dont tous les liens sont purement attaquants est un cadre de Dung : c’est en ce sens que les ADF generalisent Dung, en ajoutant supports, dependances et conditions complexes (conjonctions, disjonctions, implications) pour chaque argument.

Applications : - Modelisation de règles metier avec exceptions - Systèmes de configuration avec contraintes dependantes - Raisonnement juridique avec conditions cumulatives


Transition : De la logique aux relations de support

Les ADF permettent d’exprimer des conditions d’acceptation complexes, mais restent dans un paradigme “logique”. Les frameworks bipolaires introduisent un nouveau concept : le support.

Au lieu de seulement attaquer, les arguments peuvent maintenant soutenir d’autres arguments. Cette extension modélise mieux les débats réels où on trouve à la fois des arguments “pour” et “contre”.

Deux philosophies : - Evidential : Un seul support suffit (disjonctif) - Necessity : Tous les supports requis (conjonctif)

5.2 Frameworks Bipolaires (Evidential, Necessity)

Les cadres d’argumentation bipolaires etendent les AAFs de Dung en introduisant une relation de support distincte de l’attaque. Tweety implemente deux variantes principales :

Origine. Les frameworks d’argumentation bipolaires (BAF) — qui ajoutent une relation de support (deductive, evidential ou necessity) à la relation d’attaque — sont introduits par Cayrol, C. & Lagasquie-Schiex, M.-C. (2005), On the acceptability of arguments in bipolar argumentation frameworks. Les deux variantes implementees ici (Evidential AF, disjonctif ; Necessity AF, conjonctif) correspondent aux deux principaux modes de support formalises ulterieurement dans cette ligne de travail.

Variante Support Caractéristique
Evidential AF Disjonctif Un seul supportant suffit + arguments “prima facie”
Necessity AF Conjonctif Tous les supportants requis

Module Tweety : arg.bipolar

5.2a Evidential Argumentation Framework

Dans l’Evidential AF, les arguments peuvent etre : - Prima facie : Acceptes par defaut (supportes par l’argument special eta) - Derives : Necessitent au moins un support

L’exemple ci-dessous créé un framework avec 6 arguments, des attaques mutuelles, et un support d -> e.

# --- 5.2a Evidential Argumentation Framework ---
print("\n--- 5.2a Evidential Argumentation Framework ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple Evidential AF...")
    try:
        import jpype
        from jpype.types import *
        from java.util import HashSet, Collection, Set as JavaSet

        from org.tweetyproject.arg.dung.syntax import Argument
        from org.tweetyproject.arg.bipolar.syntax import (
             EvidentialArgumentationFramework, BArgument, ArgumentSet,
             SetAttack, SetSupport
             )
        from org.tweetyproject.arg.bipolar.reasoner.evidential import (
            SelfSupportingReasoner, GroundedReasoner as EvidentialGroundedReasoner,
            PreferredReasoner as EvidentialPreferredReasoner
            )

        print("Imports Evidential AF reussis.")

        # Creation du framework Evidential
        et = EvidentialArgumentationFramework()
        args_ev = {name: BArgument(name) for name in "abcdef"}
        for arg in args_ev.values(): 
            et.add(arg)

        # Attaques
        attack_b_a = SetAttack(args_ev['b'], args_ev['a'])
        attack_b_c = SetAttack(args_ev['b'], args_ev['c'])
        attack_c_b = SetAttack(args_ev['c'], args_ev['b'])
        attack_c_d = SetAttack(args_ev['c'], args_ev['d'])
        attack_d_f = SetAttack(args_ev['d'], args_ev['f'])
        attack_f_f = SetAttack(args_ev['f'], args_ev['f'])  # Self-attack
        
        # Support
        support_d_e = SetSupport(args_ev['d'], args_ev['e'])

        print("   Ajout des attaques et supports...")
        attacks_et = et.getAttacks()
        supports_et = et.getSupports()
        attacks_et.add(attack_b_a); attacks_et.add(attack_b_c)
        attacks_et.add(attack_c_b); attacks_et.add(attack_c_d)
        attacks_et.add(attack_d_f); attacks_et.add(attack_f_f)
        supports_et.add(support_d_e)

        # Arguments Prima Facie (supportes par eta)
        et.addPrimaFacie(args_ev['b'])
        et.addPrimaFacie(args_ev['c'])
        et.addPrimaFacie(args_ev['d'])
        et.addPrimaFacie(args_ev['f'])

        print("\nFramework Evidential cree:")
        print(str(et.prettyPrint()))

        print("\nCalcul des extensions Evidential:")
        try:
            ss_models = SelfSupportingReasoner().getModels(et)
            print(f" - Self-Supporting ({ss_models.size()} ensembles): {ss_models}")
            print(f" - Grounded: {EvidentialGroundedReasoner().getModels(et)}")
            print(f" - Preferred: {EvidentialPreferredReasoner().getModels(et)}")
        except Exception as e_ev_reason: 
            print(f"Erreur raisonnement Evidential: {e_ev_reason}")

    except ImportError as e: 
        print(f"Erreur d'import Evidential: {e}.")
    except jpype.JException as e_java: 
        print(f"Erreur Java: {e_java.message()}")
    except Exception as e_gen: 
        print(f"Erreur Python: {e_gen}")
        import traceback
        traceback.print_exc()

--- 5.2a Evidential Argumentation Framework ---
JVM prete. Execution de l'exemple Evidential AF...
Imports Evidential AF reussis.
   Ajout des attaques et supports...

Framework Evidential cree:
argument(a).
argument(b).
argument(eta).
argument(c).
argument(d).
argument(e).
argument(f).


support({eta},{f}).
support({eta},{b}).
support({eta},{c}).
support({eta},{d}).


Calcul des extensions Evidential:
 - Self-Supporting (17 ensembles): [{b,c,eta,d,f}, {eta}, {b,eta}, {eta,d}, {c,eta}, {b,eta,d}, {eta,f}, {b,c,eta}, {b,eta,f}, {c,eta,d}, {eta,d,f}, {c,eta,f}, {b,c,eta,d}, {b,eta,d,f}, {b,c,eta,f}, {}, {c,eta,d,f}]
 - Grounded: [{b,eta,c,d,f}]
 - Preferred: [{b,c,eta,d,f}]

Construction du framework Evidential

Le code suivant construit un Evidential AF avec : - 6 arguments (a à f) - Des attaques binaires entre arguments - Un support d -> e - Des arguments prima facie (b, c, d, f) qui sont “auto-justifiés”

Tweety ajoute automatiquement l’argument spécial eta pour représenter la source de vérité initiale.

5.2b Necessity Argumentation Framework

Contrairement a l’Evidential AF ou un seul support suffit, le Necessity AF exige que tous les supportants soient presents pour qu’un argument soit accepte.

Caractéristiques : - Support conjonctif : {a, b} -> c signifie que c necessite a ET b - Pas d’argument eta special - Le self-support a -> a permet a un argument de “s’auto-justifier”

# --- 5.2b Necessity Argumentation Framework ---
print("\n--- 5.2b Necessity Argumentation Framework ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple Necessity AF...")
    try:
        import jpype
        from jpype.types import *
        from java.util import HashSet, Set as JavaSet

        from org.tweetyproject.arg.bipolar.syntax import (
             NecessityArgumentationFramework, BArgument, ArgumentSet,
             BinaryAttack, BinarySupport, SetSupport
             )
        from org.tweetyproject.arg.bipolar.reasoner.necessity import (
            GroundedReasoner as NecessityGroundedReasoner,
            PreferredReasoner as NecessityPreferredReasoner
            )

        print("Imports Necessity AF reussis.")

        # Creation du framework Necessity
        nt = NecessityArgumentationFramework()
        args_nec = {name: BArgument(name) for name in "abcde"}
        for arg in args_nec.values(): 
            nt.add(arg)

        # Attaques binaires
        attack_b_a_n = BinaryAttack(args_nec['b'], args_nec['a'])
        attack_e_a_n = BinaryAttack(args_nec['e'], args_nec['a'])
        attack_c_d_n = BinaryAttack(args_nec['c'], args_nec['d'])
        
        # Supports binaires
        support_a_c_n = BinarySupport(args_nec['a'], args_nec['c'])
        support_b_b_n = BinarySupport(args_nec['b'], args_nec['b'])  # Self-support
        
        # Support ensembliste: {b, d} -> e
        supportants_s3 = ArgumentSet()
        supportants_s3.add(args_nec['b'])
        supportants_s3.add(args_nec['d'])
        supportes_s3 = HashSet()
        supportes_s3.add(args_nec['e'])
        support_set_n = SetSupport(supportants_s3, JObject(supportes_s3, JavaSet))

        print("   Ajout des attaques et supports...")
        attacks_nt = nt.getAttacks()
        supports_nt = nt.getSupports()
        attacks_nt.add(attack_b_a_n)
        attacks_nt.add(attack_e_a_n)
        attacks_nt.add(attack_c_d_n)
        supports_nt.add(support_a_c_n)
        supports_nt.add(support_b_b_n)
        supports_nt.add(support_set_n)

        print("\nFramework Necessity cree:")
        print(str(nt.prettyPrint()))

        print("\nCalcul des extensions Necessity:")
        try:
            print(f" - Grounded: {NecessityGroundedReasoner().getModels(nt)}")
            print(f" - Preferred: {NecessityPreferredReasoner().getModels(nt)}")
        except Exception as e_nec_reason: 
            print(f"Erreur raisonnement Necessity: {e_nec_reason}")

    except ImportError as e: 
        print(f"Erreur d'import Necessity: {e}.")
    except jpype.JException as e_java: 
        print(f"Erreur Java: {e_java.message()}")
    except Exception as e_gen: 
        print(f"Erreur Python: {e_gen}")
        import traceback
        traceback.print_exc()

--- 5.2b Necessity Argumentation Framework ---
JVM prete. Execution de l'exemple Necessity AF...
Imports Necessity AF reussis.
   Ajout des attaques et supports...

Framework Necessity cree:
argument(a).
argument(b).
argument(c).
argument(d).
argument(e).




Calcul des extensions Necessity:
 - Grounded: [{a,b,c,d,e}]
 - Preferred: [{a,b,c,d,e}]

Interpretation des Frameworks Bipolaires

L’argument mysterieux eta

Dans l’Evidential AF, un argument special eta (eta) apparait automatiquement. C’est l’argument evidential qui represente la “source de verite” initiale. Les arguments prima facie (b, c, d, f) sont supportes par eta, ce qui leur donne une base d’acceptation independante.

eta --[supporte]--> {b, c, d, f}  (prima facie)

Comparaison Evidential vs Necessity

Aspect Evidential AF Necessity AF
Support Ensembliste (un supportant suffit) Ensembliste (tous requis)
Prima facie Arguments auto-supportes via eta Pas de concept equivalent
Self-Supporting 17 ensembles possibles N/A
Extension Grounded {b,c,d,f,eta} {a,b,c,d,e}

Analyse Evidential AF

  • Self-Supporting (17 ensembles) : Tous les sous-ensembles qui peuvent se “justifier”
  • Grounded {b,c,d,f,eta} : Les prima facie + eta forment la base minimale
  • L’argument a n’est pas prima facie et est attaque par b, donc exclu
  • L’argument e depend du support de d (qui est attaque par c)

Analyse Necessity AF

  • Extension {a,b,c,d,e} : Tous les arguments sont acceptes
  • Le support {b,d} -> e est satisfait car b et d sont presents
  • Le self-support b -> b permet a b de “s’auto-justifier”

Application pratique

  • Evidential : Modelise les preuves juridiques (une preuve suffit)
  • Necessity : Modelise les prerequis (tous les cours requis pour un diplome)

Transition : Introduction des poids

Les frameworks bipolaires ajoutent les relations de support, mais traitent toutes les attaques comme équivalentes. Dans la réalité, certaines attaques sont plus fortes que d’autres.

Les Frameworks Pondérés (WAF) associent un poids numérique à chaque attaque. L’acceptabilité d’un argument dépend alors : - Du poids cumulé des attaques qu’il reçoit - Des seuils alpha (défense minimale) et gamma (attaque minimale)

Applications : - Débats avec arguments de différentes forces - Coûts de résolution de conflits - Probabilités d’attaques

5.3 Frameworks Pondérés (WAF)

Les Cadres d’Argumentation Pondérés (Weighted Argumentation Frameworks - WAF) associent un poids à chaque attaque, représentant sa force ou son coût. L’évaluation de l’acceptabilité prend en compte ces poids via des seuils ou des agrégations.

Tweety utilise la structure des semi-anneaux (Semiring) pour définir comment les poids sont interprétés: - WeightedSemiring: Poids numériques sommés (coûts) - FuzzySemiring: Degrés de vérité dans [0, 1] - ProbabilisticSemiring: Probabilités

# --- 5.3 Frameworks Pondérés (WAF) ---
print("\n--- 5.3 Frameworks Ponderes (WAF) ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple WAF...")
    waf_imports_ok = False
    try:
        import jpype
        from jpype.types import *

        from org.tweetyproject.arg.weighted.syntax import WeightedArgumentationFramework
        from org.tweetyproject.arg.dung.syntax import Argument, Attack, DungTheory
        from org.tweetyproject.math.algebra import WeightedSemiring
        from org.tweetyproject.arg.weighted.reasoner import (
             SimpleWeightedConflictFreeReasoner, SimpleWeightedAdmissibleReasoner,
             SimpleWeightedCompleteReasoner, SimpleWeightedPreferredReasoner,
             SimpleWeightedStableReasoner, SimpleWeightedGroundedReasoner
        )
        from org.tweetyproject.arg.dung.reasoner import (
            SimpleAdmissibleReasoner, SimpleCompleteReasoner, SimpleGroundedReasoner
        )

        print("Imports WAF et dependances reussis.")
        waf_imports_ok = True

        if waf_imports_ok:
            semiring = WeightedSemiring()
            waf = WeightedArgumentationFramework(semiring)

            a = Argument("a"); b = Argument("b"); c = Argument("c"); d = Argument("d"); e_arg = Argument("e")
            waf.add(a); waf.add(b); waf.add(c); waf.add(d); waf.add(e_arg)

            # Attaques pondérées: add(Attack, Double weight)
            waf.add(Attack(a, b), 7.0)
            waf.add(Attack(c, b), 8.0)
            waf.add(Attack(d, c), 8.0)
            waf.add(Attack(c, d), 9.0)
            waf.add(Attack(d, e_arg), 5.0)
            waf.add(Attack(e_arg, e_arg), 6.0)

            print("\nFramework Pondere (WAF) cree:")
            print(str(waf))

            print("\n--- Raisonnement Pondere ---")

            # Admissible Pondéré vs Standard
            print("\n* Admissible Pondere (alpha, gamma) vs Standard:")
            try:
                adm_reasoner_std = SimpleAdmissibleReasoner()
                weighted_adm_reasoner = SimpleWeightedAdmissibleReasoner()
                dung_theory_std = DungTheory(waf)

                adm_sets_std = adm_reasoner_std.getModels(dung_theory_std)
                print(f"  - Standard    : ({adm_sets_std.size()}) {adm_sets_std}")

                adm_sets_0_0 = weighted_adm_reasoner.getModels(waf, 0.0, 0.0)
                print(f"  - Pondere (a=0, g=0) : ({adm_sets_0_0.size()}) {adm_sets_0_0}")
                adm_sets_15_0 = weighted_adm_reasoner.getModels(waf, 15.0, 0.0)
                print(f"  - Pondere (a=15, g=0): ({adm_sets_15_0.size()}) {adm_sets_15_0}")
            except Exception as e_adm: print(f"   Erreur Weighted Admissible: {e_adm}")

            # Grounded Pondéré vs Standard
            print("\n* Grounded Pondere (alpha, gamma) vs Standard:")
            try:
                gr_reasoner_std = SimpleGroundedReasoner()
                weighted_gr_reasoner = SimpleWeightedGroundedReasoner()
                gr_set_std = gr_reasoner_std.getModel(dung_theory_std)
                print(f"  - Standard    : {{{gr_set_std}}}")

                gr_set_0_0 = weighted_gr_reasoner.getModel(waf, 0.0, 0.0)
                print(f"  - Pondere (a=0, g=0) : {{{gr_set_0_0}}}")
            except Exception as e_gr: print(f"   Erreur Weighted Grounded: {e_gr}")

    except ImportError as e: print(f"Erreur d'import pour WAF : {e}.")
    except jpype.JException as e_java: print(f"Erreur Java generale WAF: {e_java.message()}")
    except Exception as e_gen: print(f"Erreur Python inattendue WAF: {e_gen}"); import traceback; traceback.print_exc()

--- 5.3 Frameworks Ponderes (WAF) ---
JVM prete. Execution de l'exemple WAF...
Imports WAF et dependances reussis.

Framework Pondere (WAF) cree:
(<{ a, b, c, d, e },[(d,e), (c,b), (e,e), (a,b), (c,d), (d,c)]>,{(e,e)=6.0, (d,e)=5.0, (d,c)=8.0, (c,d)=9.0, (c,b)=8.0, (a,b)=7.0})

--- Raisonnement Pondere ---

* Admissible Pondere (alpha, gamma) vs Standard:
  - Standard    : (6) [{a}, {c}, {a,c}, {d}, {a,d}, {}]
  - Pondere (a=0, g=0) : (0) []
  - Pondere (a=15, g=0): (0) []

* Grounded Pondere (alpha, gamma) vs Standard:
  - Standard    : {{a}}
  - Pondere (a=0, g=0) : {{}}

Interpretation des résultats WAF

Sémantique (alpha, gamma) - relaxation de Bistarelli, Rossi & Santini

Le raisonneur SimpleWeightedAdmissibleReasoner de Tweety implemente la relaxation a deux seuils de Bistarelli, Rossi & Santini (ECSQARU 2017 ; IJAR 2018), qui prolonge les weighted argument systems de Dunne et al. (2011). Les deux paramètres ne sont pas un seuil de defense et un seuil d’attaque ; d’après le code source (WeightedArgumentationFramework.isAlphaGammaAdmissible) :

  • alpha : poids maximal tolere des attaques internes a l’ensemble (relaxation de l’absence de conflit). Avec alpha = 0, l’ensemble doit etre strictement sans conflit interne. C’est le seuil teste par isAlphaConflictFree.
  • gamma : seuil de defense = différence maximale toleree entre le poids agrege des attaques et celui des defenses. Avec gamma = 0, la defense d’un argument doit etre au moins aussi forte que les attaques subies (attaque - defense <= 0). C’est le seuil teste par gDefence.

Pourquoi les ensembles ponderes sont-ils vides - et pourquoi alpha : 0 -> 15 ne change rien ?

Les sorties (a=0, g=0) : [] puis (a=15, g=0) : [] sont coherentes une fois la sémantique comprise : augmenter alpha ne relache que la tolerance au conflit interne, alors que la contrainte bloquante ici est la defense (gamma = 0, inchangee). Tant que gamma n’est pas relache, le résultat reste vide - relacher alpha seul est sans effet. De plus, gDefence renvoie faux lorsqu’un ensemble ne subit aucune attaque externe pertinente : l’ensemble vide et les singletons non attaques (ex. {a}, qui n’est attaque par personne) echouent donc le test de defense sous ces reglages stricts. C’est ce qui rend la sémantique ponderee (0 ensemble) bien plus restrictive que l’admissibilite standard de Dung (6 ensembles).

Attaques ponderees du graphe (telles que construites dans le code) :

a --7.0--> b
c --8.0--> b
c --9.0--> d     d --8.0--> c     (attaque mutuelle c <-> d)
d --5.0--> e
e --6.0--> e     (auto-attaque)
Sémantique Admissibles Grounded
Standard (Dung) 6 : {}, {a}, {c}, {d}, {a,c}, {a,d} {a}
Pondere (alpha=0, gamma=0) 0 {}

Pour obtenir des ensembles non vides

Il faut relacher gamma (le seuil de defense) au-dela du plus grand ecart attaque/defense du graphe - et non augmenter alpha. La valeur exacte depend des poids ; elle n’est pas exercee dans ce notebook (laissee en exercice). Le alpha=20.0 recommande dans une version anterieure de cette cellule etait un ajustement jamais teste, et portait de surcroit sur le mauvais paramètre.

Sources : P. Dunne, A. Hunter, P. McBurney, S. Parsons, M. Wooldridge, Weighted argument systems: Basic definitions, illustrations, and emerging results (Artificial Intelligence, 2011) ; S. Bistarelli, F. Rossi, F. Santini, A relaxation of internal conflict and defence in weighted argumentation frameworks (ECSQARU 2017) et A novel weighted defence and its relaxation in abstract argumentation (IJAR, 2018).

Exercice : Debat avec attaques ponderees (WAF)

La section 5.3 a montre les Frameworks Ponderes avec seuils alpha et gamma. Modelisez un debat ou certaines attaques sont plus fortes que d’autres.

Contexte

Trois experts : a (“Investir maintenant”), b (“Le marche est instable”, attaque a, poids 6.0), c (“Les indicateurs sont solides”, attaque b, poids 9.0).

Indices :

  • semiring = WeightedSemiring(), waf = WeightedArgumentationFramework(semiring)
  • waf.add(Attack(src, tgt), poids)
  • SimpleWeightedGroundedReasoner().getModel(waf, alpha, gamma)
# --- Exercice : Debat avec attaques ponderees (WAF) ---
# TODO etudiant : modelisez un debat d'experts avec des attaques ponderees
#
# Etape 1 : imports (cf section 5.3)
#   from org.tweetyproject.arg.weighted.syntax import WeightedArgumentationFramework
#   from org.tweetyproject.arg.dung.syntax import Argument, Attack, DungTheory
#   from org.tweetyproject.math.algebra import WeightedSemiring
#   from org.tweetyproject.arg.weighted.reasoner import SimpleWeightedGroundedReasoner
#   from org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasoner
#
# Etape 2 : creer le semiring et le WeightedArgumentationFramework
# Etape 3 : ajouter a, b, c puis les attaques ponderees b->a (6.0), c->b (9.0)
# Etape 4 : calculer le grounded pondere (alpha=0, gamma=0) ET le grounded standard
# Etape 5 (bonus) : faire varier alpha (ex: 10.0) et observer l'effet

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    waf = None               # TODO etudiant : remplacer par le WeightedArgumentationFramework
    grounded_pondere = None   # TODO etudiant : remplacer par le grounded pondere
    grounded_standard = None  # TODO etudiant : remplacer par le grounded standard
    print("Exercice a completer")
Exercice a completer

5.4 Frameworks Sociaux (SAF)

Les Cadres d’Argumentation Sociaux (SAF) [Leite, Martins, 2011] permettent d’associer des votes (positifs ou négatifs) aux arguments. Ces votes influencent la force ou l’acceptabilité finale des arguments.

  • Sémantique ISS (Iterated Schema Semantics): Calcule un score pour chaque argument basé sur les scores de ses attaquants et sur les votes, jusqu’à convergence.
# --- 5.4 Frameworks Sociaux (SAF) ---
print("\n--- 5.4 Frameworks Sociaux (SAF) ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple SAF...")
    saf_imports_ok = False
    try:
        import jpype
        from jpype.types import *
        try:
            from org.tweetyproject.arg.social.syntax import SocialAbstractArgumentationFramework
            from org.tweetyproject.arg.dung.syntax import Argument, Attack
            from org.tweetyproject.arg.social.reasoner import IssReasoner
            from org.tweetyproject.arg.social.semantics import SimpleProductSemantics
            print("Imports SAF directs reussis.")
            saf_imports_ok = True
        except ImportError:
            print("Imports directs SAF echoues. Tentative avec JClass...")
            SocialAbstractArgumentationFramework = jpype.JClass("org.tweetyproject.arg.social.syntax.SocialAbstractArgumentationFramework")
            Argument = jpype.JClass("org.tweetyproject.arg.dung.syntax.Argument")
            Attack = jpype.JClass("org.tweetyproject.arg.dung.syntax.Attack")
            IssReasoner = jpype.JClass("org.tweetyproject.arg.social.reasoner.IssReasoner")
            SimpleProductSemantics = jpype.JClass("org.tweetyproject.arg.social.semantics.SimpleProductSemantics")
            print("Imports SAF via JClass reussis.")
            saf_imports_ok = True

        from java.util import Collection

        if saf_imports_ok:
            saf = SocialAbstractArgumentationFramework()
            A = Argument("A"); B = Argument("B"); C = Argument("C"); D = Argument("D")
            saf.add(A); saf.add(B); saf.add(C); saf.add(D)

            try:
                # NB: saf.getAttacks() retourne une COPIE DEFENSIVE chez
                # SocialAbstractArgumentationFramework -> .add() dessus ne modifie
                # PAS le framework (les attaques restent absentes, ISS tourne sans
                # propagation). On ajoute directement via addAttack(attacker, attacked).
                saf.addAttack(A, B); saf.addAttack(B, C)
                saf.addAttack(C, B); saf.addAttack(C, D)
                print("   Attaques ajoutees avec succes.")

                # Votes
                saf.voteUp(A, 3); saf.voteDown(A, 1)  # A: +2 net
                saf.voteUp(B, 2)                       # B: +2 net
                saf.voteUp(C, 2); saf.voteDown(C, 5)  # C: -3 net
                saf.voteUp(D, 2); saf.voteDown(D, 1)  # D: +1 net

                print("\nFramework Social (SAF) cree:")
                print(str(saf))

                print("\nCalcul du modele avec ISS (Iterated Schema Semantics)...")
                try:
                    iss_reasoner = IssReasoner(SimpleProductSemantics(0.01), 0.001)
                    iss_model = iss_reasoner.getModel(saf)
                    print("\nModele ISS (scores d'acceptabilite):\n", str(iss_model))
                except jpype.JException as e_iss_java: print(f"Erreur Java lors du raisonnement ISS: {e_iss_java.message()}")
                except Exception as e_iss_py: print(f"Erreur Python lors du raisonnement ISS: {e_iss_py}")

            except Exception as e_add_attack:
                 print(f"Erreur lors de l'ajout d'attaques via getAttacks().add(): {e_add_attack}")

    except ImportError as e: print(f"Erreur d'import initiale pour SAF : {e}.")
    except jpype.JException as e_java: print(f"Erreur Java generale: {e_java.message()}")
    except Exception as e_gen: print(f"Erreur Python inattendue: {e_gen}"); import traceback; traceback.print_exc()

--- 5.4 Frameworks Sociaux (SAF) ---
JVM prete. Execution de l'exemple SAF...
Imports SAF directs reussis.
   Attaques ajoutees avec succes.

Framework Social (SAF) cree:
<{A(+3-1),B(+2-0),C(+2-5),D(+2-1)},[(B,C), (C,B), (A,B), (C,D)]>

Calcul du modele avec ISS (Iterated Schema Semantics)...

Modele ISS (scores d'acceptabilite):
 {A=0.7481296758104738, B=0.19288319912917049, C=0.23027583477056476, D=0.5114446280594254}

Interpretation des scores ISS

Le modèle ISS (Iterated Schema Semantics) calcule un score d’acceptabilite pour chaque argument :

Scores obtenus :

Argument Score Votes (up-down) Interpretation
A 0.748 +3 -1 = +2 Bien accepte ; A n’est attaque par personne
B 0.193 +2 -0 = +2 Fortement penalise : attaque par A (0.748) ET C (0.230)
C 0.230 +2 -5 = -3 Faible : votes negatifs (-3) ET attaque par B
D 0.511 +2 -1 = +1 Modere : attaque par C (0.230), attaquant faible

Mécanisme ISS :

  1. Score initial base sur les votes : score = up / (up + down)
  2. Propagation via les attaques : le score d’un argument diminue si ses attaquants ont des scores eleves
  3. Itération jusqu’a convergence (epsilon = 0.001)

Analyse du graphe : - A -> B et B -> C et C -> B et C -> D - B est attaque par A (score 0.748) et C (score 0.230) : la double attaque, dont l’attaquant A est fort, fait chuter B a 0.193 malgre ses +2 votes. - A (0.748) n’a aucun attaquant : son score ne depend que de ses propres votes. - C (0.230) subit ses votes negatifs (-3) ET l’attaque de B.

Application pratique : - Modeliser les debats sur reseaux sociaux (likes/dislikes) - Les arguments populaires (beaucoup de upvotes) resistent mieux aux attaques - Un argument très attaque peut survivre si ses attaquants sont faibles (cf. D attaque par C=0.230, garde 0.511)

5.5 Set Argumentation Frameworks (SetAF)

Les Set Argumentation Frameworks [Nielsen, Parsons, 2006] généralisent les attaques: c’est un ensemble d’arguments qui attaque collectivement un argument.

  • Attaque d’ensemble: \((X, a)\) où \(X\) est un ensemble non vide d’arguments et \(a\) est l’argument attaqué
  • Défense: Un argument \(a\) est défendu par \(E\) si pour chaque \(X\) qui attaque \(a\), un sous-ensemble de \(E\) attaque un élément de \(X\)
# --- 5.5 Set Argumentation Frameworks (SetAF) ---
print("\n--- 5.5 Set Argumentation Frameworks (SetAF) ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple SetAF...")
    setaf_imports_ok = False
    try:
        import jpype
        from jpype.types import *
        from java.util import HashSet, Set as JavaSet

        from org.tweetyproject.arg.setaf.syntax import SetAf, SetAttack
        from org.tweetyproject.arg.dung.syntax import Argument
        from org.tweetyproject.arg.setaf.reasoners import SimpleGroundedSetAfReasoner, SimpleAdmissibleSetAfReasoner, SimplePreferredSetAfReasoner

        print("Imports SetAF et dependances reussis.")
        setaf_imports_ok = True

        if setaf_imports_ok:
            set_af = SetAf()
            a = Argument("a"); b = Argument("b"); c = Argument("c"); d_arg = Argument("d")
            set_af.add(a); set_af.add(b); set_af.add(c); set_af.add(d_arg)

            # Créer les ensembles attaquants
            attacker_set1 = HashSet()
            attacker_set1.add(b); attacker_set1.add(d_arg)

            attacker_set2 = HashSet()
            attacker_set2.add(c); attacker_set2.add(a)

            # Ajouter les attaques d'ensemble
            set_attack1 = SetAttack(JObject(attacker_set1, JavaSet), a)
            set_attack2 = SetAttack(JObject(attacker_set2, JavaSet), c)
            set_af.add(set_attack1); set_af.add(set_attack2)

            print("\nFramework SetAF cree:")
            print(str(set_af))
            print(f"   Arguments: {set_af.getNodes()}")
            print(f"   Attaques Set: {set_af.getAttacks()}")

            print("\n--- Raisonnement SetAF ---")
            try:
                gr_setaf_reasoner = SimpleGroundedSetAfReasoner()
                gr_setaf_extension = gr_setaf_reasoner.getModel(set_af)
                print(f"\n* Extension Fondee (Grounded): {gr_setaf_extension}")

                adm_setaf_reasoner = SimpleAdmissibleSetAfReasoner()
                adm_setaf_extensions = adm_setaf_reasoner.getModels(set_af)
                print(f"\n* Extensions Admissibles ({adm_setaf_extensions.size()}): {adm_setaf_extensions}")

                pref_setaf_reasoner = SimplePreferredSetAfReasoner()
                pref_setaf_extensions = pref_setaf_reasoner.getModels(set_af)
                print(f"\n* Extensions Preferees ({pref_setaf_extensions.size()}): {pref_setaf_extensions}")

            except jpype.JException as e_reason_java: print(f"Erreur Java lors du raisonnement SetAF: {e_reason_java.message()}")
            except Exception as e_reason_py: print(f"Erreur Python lors du raisonnement SetAF: {e_reason_py}")

    except ImportError as e: print(f"Erreur d'import pour SetAF : {e}. Verifiez le JAR 'arg.setaf'.")
    except jpype.JException as e_java: print(f"Erreur Java generale SetAF: {e_java.message()}")
    except Exception as e_gen: print(f"Erreur Python inattendue SetAF: {e_gen}"); import traceback; traceback.print_exc()

--- 5.5 Set Argumentation Frameworks (SetAF) ---
JVM prete. Execution de l'exemple SetAF...
Imports SetAF et dependances reussis.

Framework SetAF cree:
<[a, b, c, d],[([b, d],a), ([a, c],c)]>
   Arguments: [a, b, c, d]
   Attaques Set: [([b, d],a), ([a, c],c)]

--- Raisonnement SetAF ---

* Extension Fondee (Grounded): {b,c,d}

* Extensions Admissibles (5): [{b}, {d}, {b,d}, {b,c,d}, {}]

* Extensions Preferees (1): [{b,c,d}]

Interpretation des résultats SetAF

Structure du framework

Arguments: {a, b, c, d}
Attaques collectives:
  {b, d} --attaque--> a   (b ET d ensemble attaquent a)
  {a, c} --attaque--> c   (a ET c ensemble attaquent c) 

Différence avec Dung

Dans un framework de Dung classique, chaque attaque est binaire : x -> y. Dans SetAF, un ensemble d’arguments attaque collectivement : {x1, x2, ...} -> y.

L’attaque {b, d} -> a signifie que a est attaque uniquement si b ET d sont tous deux presents. Si un seul manque, l’attaque n’a pas lieu.

Analyse de l’extension Grounded : {b, c, d}

Argument Statut Raison
b Accepte Aucune attaque contre b
d Accepte Aucune attaque contre d
c Accepte L’attaque {a,c}->c necessite a, mais a est rejete
a Rejete Attaque par {b,d}, et b et d sont tous deux acceptes

Pourquoi a est rejete ?

  1. L’attaque {b, d} -> a est activee car b et d sont dans l’extension
  2. Pour defendre a, il faudrait attaquer b ou d
  3. Aucun argument n’attaque b ou d, donc a ne peut pas etre defendu

Pourquoi c survit a l’attaque {a, c} -> c ?

L’attaque {a, c} -> c est paradoxale : elle necessite c pour attaquer c. Puisque a est rejete, l’ensemble {a, c} n’est jamais “complet” dans l’extension, donc l’attaque n’est pas activee.

Applications pratiques

  • Vote a l’unanimite : Une decision est bloquee seulement si TOUS les opposants votent contre
  • Systèmes de securite : Une alerte se declenche si TOUTES les conditions sont reunies
  • Consensus : Un argument est rejete seulement si un groupe entier s’y oppose

5.6 Frameworks Étendus (Attaques sur Attaques)

Les Frameworks d’Argumentation Étendus [Modgil, 2009] permettent de modéliser des scénarios où une attaque peut être attaquée par un argument. Cela représente des concepts comme la préférence entre attaques.

  • EAF (Extended AF): Arguments attaquent des attaques \((c, (a, b))\)
  • REAF (Récursive Extended AF): Généralise les EAF en permettant aux arguments d’attaquer des attaques sur des attaques (récursivement)
# --- 5.6 Frameworks Étendus (EAF / REAF) ---
print("\n--- 5.6 Frameworks Etendus (EAF / REAF) ---")

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    print("JVM prete. Execution de l'exemple EAF/REAF...")
    eaf_reaf_imports_ok = False
    try:
        import jpype
        from jpype.types import *
        from org.tweetyproject.arg.dung.syntax import Argument, Attack
        from org.tweetyproject.arg.extended.syntax import ExtendedTheory, RecursiveExtendedTheory, ExtendedAttack
        from org.tweetyproject.arg.extended.reasoner import SimpleExtendedCompleteReasoner, SimpleRecursiveExtendedCompleteReasoner

        print("Imports EAF/REAF reussis.")
        eaf_reaf_imports_ok = True

        if eaf_reaf_imports_ok:
            print("\n--- Exemple Extended AF (EAF) ---")
            eaf_theory = ExtendedTheory()
            a_eaf = Argument("a_e"); b_eaf = Argument("b_e"); c_eaf = Argument("c_e")
            d_eaf = Argument("d_e"); e_eaf = Argument("e_e")
            eaf_theory.add(a_eaf); eaf_theory.add(b_eaf); eaf_theory.add(c_eaf)
            eaf_theory.add(d_eaf); eaf_theory.add(e_eaf)

            # Attaques standard
            print("   Ajout attaques standard EAF...")
            eaf_theory.addAttack(a_eaf, b_eaf); eaf_theory.addAttack(b_eaf, a_eaf)
            eaf_theory.addAttack(c_eaf, d_eaf); eaf_theory.addAttack(d_eaf, c_eaf)
            print("   Attaques standard ajoutees.")

            # Objets Attack cibles
            attack_ba_target = Attack(b_eaf, a_eaf)
            attack_ab_target = Attack(a_eaf, b_eaf)
            attack_cd_target = Attack(c_eaf, d_eaf)

            # Attaques étendues (Arg -> Attack)
            print("   Ajout attaques etendues EAF...")
            eaf_theory.addAttack(c_eaf, attack_ba_target)
            eaf_theory.addAttack(d_eaf, attack_ab_target)
            eaf_theory.addAttack(e_eaf, attack_cd_target)
            print("   Attaques etendues ajoutees.")

            print("\nFramework EAF cree:")
            try: print(str(eaf_theory.prettyPrint()))
            except: print(str(eaf_theory))

            print(f"\nCalcul des Extensions Completes (EAF)...")
            try:
                eaf_reasoner = SimpleExtendedCompleteReasoner()
                eaf_extensions = eaf_reasoner.getModels(eaf_theory)
                print(f"Extensions Completes (EAF): ({eaf_extensions.size()})")
                for ext in eaf_extensions: print(f"  - {ext}")
            except Exception as e_eaf_reason: print(f"Erreur raisonnement EAF: {e_eaf_reason}")

            # --- Exemple REAF ---
            print("\n\n--- Exemple Recursive Extended AF (REAF) ---")
            reaf_theory = RecursiveExtendedTheory()
            a_reaf = Argument("a_r"); b_reaf = Argument("b_r"); c_reaf = Argument("c_r")
            d_reaf = Argument("d_r"); e_reaf = Argument("e_r"); f_reaf = Argument("f_r")
            reaf_theory.add(a_reaf); reaf_theory.add(b_reaf); reaf_theory.add(c_reaf)
            reaf_theory.add(d_reaf); reaf_theory.add(e_reaf); reaf_theory.add(f_reaf)

            print("   Ajout attaques standard REAF...")
            reaf_theory.addAttack(a_reaf, b_reaf); reaf_theory.addAttack(b_reaf, a_reaf)
            reaf_theory.addAttack(d_reaf, c_reaf); reaf_theory.addAttack(c_reaf, d_reaf)
            print("   Attaques standard ajoutees.")

            # ExtendedAttack cibles niveau 1
            attack_ab_reaf_target = ExtendedAttack(a_reaf, b_reaf)
            attack_ba_reaf_target = ExtendedAttack(b_reaf, a_reaf)
            attack_cd_reaf_target = ExtendedAttack(c_reaf, d_reaf)

            print("   Ajout attaques etendues REAF (niveau 1)...")
            reaf_theory.addAttack(c_reaf, JObject(attack_ba_reaf_target, ExtendedAttack))
            reaf_theory.addAttack(d_reaf, JObject(attack_ab_reaf_target, ExtendedAttack))
            reaf_theory.addAttack(e_reaf, JObject(attack_cd_reaf_target, ExtendedAttack))
            print("   Attaques etendues (niveau 1) ajoutees.")

            # Niveau 2
            attack_e_cd_target_lvl2 = ExtendedAttack(e_reaf, JObject(attack_cd_reaf_target, ExtendedAttack))
            print("   Ajout attaque etendue REAF (niveau 2)...")
            reaf_theory.addAttack(f_reaf, JObject(attack_e_cd_target_lvl2, ExtendedAttack))
            print("   Attaque etendue (niveau 2) ajoutee.")

            print("\nFramework REAF cree:")
            try: print(str(reaf_theory.prettyPrint()))
            except: print(str(reaf_theory))

            print(f"\nCalcul des Extensions Completes (REAF)...")
            try:
                reaf_reasoner = SimpleRecursiveExtendedCompleteReasoner()
                reaf_extensions = reaf_reasoner.getModels(reaf_theory)
                print(f"Extensions Completes (REAF): ({reaf_extensions.size()})")
                for ext in reaf_extensions: print(f"  - {ext}")
            except Exception as e_reaf_reason: print(f"Erreur raisonnement REAF: {e_reaf_reason}")

    except ImportError as e: print(f"Erreur d'import pour EAF/REAF : {e}. Verifiez le JAR 'arg.extended'.")
    except jpype.JException as e_java: print(f"Erreur Java generale EAF/REAF: {e_java.message()}")
    except Exception as e_gen: print(f"Erreur Python inattendue EAF/REAF: {e_gen}"); import traceback; traceback.print_exc()

--- 5.6 Frameworks Etendus (EAF / REAF) ---
JVM prete. Execution de l'exemple EAF/REAF...
Imports EAF/REAF reussis.

--- Exemple Extended AF (EAF) ---
   Ajout attaques standard EAF...
   Attaques standard ajoutees.
   Ajout attaques etendues EAF...
   Attaques etendues ajoutees.

Framework EAF cree:
argument(a_e).
argument(c_e).
argument(b_e).
argument(e_e).
argument(d_e).

attack(e_e,(c_e,d_e)).
attack(a_e,b_e).
attack(d_e,c_e).
attack(b_e,a_e).
attack(c_e,d_e).
attack(c_e,(b_e,a_e)).
attack(d_e,(a_e,b_e)).


Calcul des Extensions Completes (EAF)...
Extensions Completes (EAF): (1)
  - {b_e,e_e,d_e}


--- Exemple Recursive Extended AF (REAF) ---
   Ajout attaques standard REAF...
   Attaques standard ajoutees.
   Ajout attaques etendues REAF (niveau 1)...
   Attaques etendues (niveau 1) ajoutees.
   Ajout attaque etendue REAF (niveau 2)...
   Attaque etendue (niveau 2) ajoutee.

Framework REAF cree:
argument(b_r).
argument(a_r).
argument(d_r).
argument(c_r).
argument(f_r).
argument(e_r).

attack(d_r,(a_r,b_r)).
attack(c_r,(b_r,a_r)).
attack(f_r,(e_r,(c_r,d_r))).
attack(a_r,b_r).
attack(d_r,c_r).
attack(b_r,a_r).
attack(c_r,d_r).
attack(e_r,(c_r,d_r)).


Calcul des Extensions Completes (REAF)...
Extensions Completes (REAF): (3)
  - [b_r, (d_r,(a_r,b_r)), d_r, f_r, e_r, (f_r,(e_r,(c_r,d_r))), (d_r,c_r), (b_r,a_r)]
  - [a_r, c_r, (c_r,(b_r,a_r)), f_r, e_r, (f_r,(e_r,(c_r,d_r))), (a_r,b_r), (c_r,d_r)]
  - [f_r, e_r, (f_r,(e_r,(c_r,d_r)))]

Interpretation des frameworks etendus EAF/REAF

Les résultats montrent comment les attaques sur attaques modifient les extensions :

EAF : Extensions Completes

Une seule extension : {b_e, e_e, d_e}

Analyse : - a_e <-> b_e : conflit symetrique - c_e attaque l’attaque (b_e, a_e) -> desactive cette attaque - d_e attaque l’attaque (a_e, b_e) -> desactive cette attaque - e_e attaque l’attaque (c_e, d_e) -> protege d_e - Résultat : b_e, d_e et e_e forment l’unique extension

REAF : Extensions Completes (3 extensions)

Extension Contenu simplifie Interpretation
1 {b_r, d_r, f_r, e_r, ...} Camp b/d avec meta-attaques
2 {a_r, c_r, f_r, e_r, ...} Camp a/c avec meta-attaques
3 {f_r, e_r, ...} Position minimale (meta-args seulement)

Recursivite en action : - Niveau 1 : c_r attaque (b_r, a_r) - Niveau 1 : e_r attaque (c_r, d_r) - Niveau 2 : f_r attaque (e_r, (c_r, d_r)) -> meta-meta-attaque

Application pratique : - EAF/REAF modelisent les debats sur la pertinence des arguments - “Je conteste que ton argument attaque le mien” (meta-argumentation) - Utile en droit, philosophie, et negociation

Exemple guide : Modelisation d’un debat avec un framework bipolaire

Contexte

Voici une modelisation guidee d’un debat sur le choix d’un langage de programmation. Etudiez la solution complete ci-dessous, puis traitez l’exercice qui suit.

Arguments : - a : “Python est facile a apprendre” - b : “Python est lent pour le calcul intensif” - c : “NumPy compense la lenteur de Python” (support de a, attaque b) - d : “Java a un typage statique plus sur” - e : “Le typage statique ralentit le développement” (attaque d) - f : “Les IDE modernes compensent le typage” (support de d, attaque e)

Relations : - Attaques : b attaque a, c attaque b, e attaque d, f attaque e - Supports : c supporte a, f supporte d

Objectifs

  1. Construire un DungTheory avec les 6 arguments et les attaques
  2. Calculer les extensions grounded et preferred
  3. (Bonus) Si les imports bipolaires fonctionnent, construire un NecessityArgumentationFramework ou EvidentialArgumentationFramework avec les relations de support
  4. Interpreter les résultats : quel langage “gagne” le debat ?

Indices :

  • DungTheory, Argument, Attack pour le framework de base
  • SimpleGroundedReasoner().getModel(theory) pour l’extension grounded
  • SimplePreferredReasoner().getModels(theory) pour les extensions preferred
  • Les supports bipolaires utilisent Support(source, target) et NecessityArgumentationFramework
# --- Exemple guide : Debat langage de programmation (Framework bipolaire) ---

if jvm_ready:
    from org.tweetyproject.arg.dung.syntax import DungTheory, Argument, Attack
    from org.tweetyproject.arg.dung.reasoner import SimpleGroundedReasoner, SimplePreferredReasoner

    # 1. Creer les arguments
    a = Argument("a")  # Python facile
    b = Argument("b")  # Python lent
    c = Argument("c")  # NumPy compense
    d = Argument("d")  # Java typage sur
    e = Argument("e")  # Typage ralentit
    f = Argument("f")  # IDE compense

    # 2. Construire le framework
    theory = DungTheory()
    for arg in [a, b, c, d, e, f]:
        theory.add(arg)

    theory.add(Attack(b, a))
    theory.add(Attack(c, b))
    theory.add(Attack(e, d))
    theory.add(Attack(f, e))

    print("Framework de Dung cree:")
    print(str(theory))

    # 3. Calculer les extensions
    grounded = SimpleGroundedReasoner().getModel(theory)
    print("\nExtension grounded:", grounded)

    preferred = SimplePreferredReasoner().getModels(theory)
    print("Extensions preferred:", preferred)

    # 4. Interpreter : quels arguments sont acceptes ?
    accepted = sorted(str(arg) for arg in grounded)
    print("\nArguments acceptes (grounded):", accepted)
    python_ok = "a" in accepted
    java_ok = "d" in accepted
    print(f"  Python (a) accepte : {python_ok}")
    print(f"  Java   (d) accepte : {java_ok}")
    print("Conclusion: les deux langages 'gagnent', chaque critique etant neutralisee.")

    # 5. (Bonus) Relations de support avec un framework bipolaire (Necessity)
    try:
        from org.tweetyproject.arg.bipolar.syntax import (
            NecessityArgumentationFramework, BArgument, BinaryAttack, BinarySupport
        )
        from org.tweetyproject.arg.bipolar.reasoner.necessity import (
            GroundedReasoner as NecGroundedReasoner
        )

        bargs = {name: BArgument(name) for name in "abcdef"}
        naf = NecessityArgumentationFramework()
        for arg in bargs.values():
            naf.add(arg)

        for src, tgt in [("b", "a"), ("c", "b"), ("e", "d"), ("f", "e")]:
            naf.getAttacks().add(BinaryAttack(bargs[src], bargs[tgt]))
        for src, tgt in [("c", "a"), ("f", "d")]:
            naf.getSupports().add(BinarySupport(bargs[src], bargs[tgt]))

        print("\nBonus - Framework bipolaire (Necessity):")
        print(str(naf.prettyPrint()))
        print("Grounded (Necessity):", NecGroundedReasoner().getModels(naf))
    except Exception as e_bonus:
        print(f"\nBonus non execute: {e_bonus}")
else:
    print("ERREUR: JVM non demarree. Exemple guide (debat langage) non execute.")
Framework de Dung cree:
<{ a, b, c, d, e, f },[(c,b), (e,d), (b,a), (f,e)]>

Extension grounded: {a,c,d,f}
Extensions preferred: [{a,c,d,f}]

Arguments acceptes (grounded): ['a', 'c', 'd', 'f']
  Python (a) accepte : True
  Java   (d) accepte : True
Conclusion: les deux langages 'gagnent', chaque critique etant neutralisee.

Bonus - Framework bipolaire (Necessity):
argument(a).
argument(b).
argument(c).
argument(d).
argument(e).
argument(f).



Grounded (Necessity): [{a,b,c,d,e,f}]

Exercice : Modelisation d’un debat avec un framework bipolaire

Contexte

A votre tour. Modelisez un debat sur le choix d’une architecture logicielle (monolithe vs microservices) :

Arguments suggeres : - m1 : “Le monolithe est simple a deployer” - m2 : “Le monolithe devient difficile a maintenir a grande echelle” - s1 : “Les microservices isolent les pannes” - s2 : “Les microservices ajoutent de la complexite reseau” - s3 : “Un bon outillage (Kubernetes) reduit la complexite reseau” (support de s1, attaque s2)

Objectifs

  1. Construire un DungTheory avec vos arguments et des attaques coherentes
  2. Calculer les extensions grounded et preferred
  3. Interpreter : quelle architecture “gagne” selon votre modelisation ?
  4. (Bonus) Ajouter les relations de support avec un framework bipolaire (Necessity / Evidential)

Indices :

  • Reprenez la structure de l’exemple guide ci-dessus
  • DungTheory, Argument, Attack pour le framework de base
  • SimpleGroundedReasoner().getModel(theory) et SimplePreferredReasoner().getModels(theory)
# --- Exercice : Debat architecture logicielle (Framework bipolaire) ---
# TODO etudiant : modelisez le debat monolithe vs microservices
# 1. Creer les arguments  2. Construire le DungTheory  3. Calculer les extensions
# 4. Interpreter le resultat  5. (Bonus) ajouter les supports (framework bipolaire)
print("Exercice a completer : voir l'exemple guide ci-dessus comme modele.")
Exercice a completer : voir l'exemple guide ci-dessus comme modele.

Exercice : Attaques collectives (SetAF)

La section 5.5 a introduit les SetAF : un ensemble d’arguments attaque collectivement une cible. L’attaque {x, y} -> z n’est active que si x ET y sont tous deux acceptes.

Contexte

Un comite de 3 membres (m1, m2, m3) peut bloquer une proposition prop, mais seulement s’ils s’opposent tous les trois ensemble : - Attaque collective : {m1, m2, m3} -> prop - temoin attaque m2 (un temoignage discredite m2)

Si m2 tombe, l’attaque collective contre prop n’est plus complete.

Indices :

  • set_af = SetAf(), puis SetAttack(JObject(attacker_set, JavaSet), cible)
  • SimpleGroundedSetAfReasoner().getModel(set_af) pour le grounded
# --- Exercice : Attaques collectives (SetAF) ---
# TODO etudiant : modelisez une decision a l'unanimite avec un SetAF
#
# Etape 1 : imports (cf section 5.5)
#   from org.tweetyproject.arg.setaf.syntax import SetAf, SetAttack
#   from org.tweetyproject.arg.dung.syntax import Argument
#   from org.tweetyproject.arg.setaf.reasoners import SimpleGroundedSetAfReasoner
#   from java.util import HashSet, Set as JavaSet
#   from jpype.types import JObject
#
# Etape 2 : creer le SetAf et ajouter prop, m1, m2, m3, temoin
# Etape 3 : construire {m1, m2, m3} (HashSet) et l'attaque collective -> prop
# Etape 4 : ajouter temoin -> m2 et calculer le grounded
# Etape 5 (bonus) : retirer temoin -> m2 et re-calculer

if not jvm_ready:
    print("ERREUR: JVM non demarree.")
else:
    set_af = None       # TODO etudiant : remplacer par le SetAf construit
    extension = None    # TODO etudiant : remplacer par SimpleGroundedSetAfReasoner().getModel(set_af)
    print("Exercice a completer")
Exercice a completer

Note-de-parite cross-langage (cycle c.170 – Tweety-7a jumeau Python <-> C#, tranche 2 IKVM)

Le notebook jumeau Tweety-07a-Extended-Frameworks-CSharp.ipynb couvre les memes frameworks que ce notebook-ci, mais selon une architecture fondamentalement differente au depart (tranche 1, from-scratch), puis selon une architecture a nouveau differente depuis la tranche 2 (lib-vs-lib via IKVM). Les chiffres ci-dessous sont ancres sur les cellules qui les mesurent : ils peuvent etre re-verifies par les commandes en fin de note ; cette note ne tient pas en l’air.

Aspect Python (ce notebook) C# jumeau (tranche 1) C# jumeau (tranche 2)
Moteur JVM Tweety via jpype (42 JARs charges, init_tweety()) BCL .NET 9 from-scratch (0 NuGet, 0 jpype, 0 IKVM, 0 JVM) Pont IKVM + shade org.tweetyproject.tweety-7a.dll (cell 23)
Dep externe runtime JDK zulu17.50.19 + libs natives minisat.dll Aucune JDK + IKVM + 8 DLLs Tweety (cell 19)
ADF (5.1) NativeMinisatSolver + IncrementalSatSolver (grounded {t(a), t(c), f(b)}) ADF + Kleene 3-valued from-scratch (grounded {a,c}) arg.dung via lib (cell 28) ; arg.adf via lib (cell 37)
SetAF (5.5) SetAf + SetAttack Java + grounded {b,c,d} SetAF C# grounded {b,c,d} (meme resultat) Absent du shade (cell 41 : 0 type dans arg.setaf)
EAF (5.6) ExtendedTheory + SimpleExtendedCompleteReasoner EAF C# avec meta-attaques Modgil + reinstatement ({a,c} Dung vs {a,b,c} EAF) Absent du shade (cell 41 : 0 type dans arg.eaf ET arg.extended)
Bipolar (5.7) BipolarFramework Java non porte (pas de jumeau tranche 1) Absent du shade (cell 41 : 0 type dans arg.bipolar, attention BipolarSatEncoding est dans arg.adf.reasoner.sat)
Exercises 3 stubs (WAF cell 20, bipolar cell 33, SetAF cell 35) 4 stubs (ADF cell 18, SetAF cell 19, EAF cell 20, VAF cell 21) 4 stubs (ADF cell 45, SetAF cell 47, EAF cell 49, VAF cell 51)

Frameworks uniquement Python (Tweety ecosystem) : Evidential BAF (5.2a), Necessity BAF (5.2b), WAF (5.3, semiring pondere), SAF (5.4, votes + ISS), REAF (5.6 niveau 2 recursif). Ces frameworks n’ont pas de pendant C# : ni en tranche 1 (from-scratch) ni en tranche 2 (le shade ne les contient pas).

Frameworks uniquement C# tranche 1 : VAF (Value-based AF, Bench-Capon) avec ordre de preference entre valeurs (Economie > Environnement -> grounded {a} ; inverse -> grounded {a,b}). La tranche 2 n’a pas re-sonde VAF (cell 39 limite la sonde a ADF/SetAF/EAF/Bipolar) – l’asymetrie Python / C# est preservee sur ce framework.

Substance pedagogique distincte (cycle c.170 ★★) :

  • Python notebook montre l’usage de l’ecosysteme Tweety complet (dependance lourde mais riche : 7 frameworks ADF+Evidential+Necessity+WAF+SAF+SetAF+EAF/REAF, solveurs SAT natifs via JNI).
  • C# jumeau tranche 1 montre qu’on peut implementer le substrat mathematique sans JVM (Kleene 3-valued, ADF fixed-point, SetAF labelling, EAF reinstatement, VAF value-pref) en pure BCL .NET 9 – pedagogie de l’implementation, pas de l’usage.
  • C# jumeau tranche 2 montre la lib-vs-lib : refaire un calcul qu’on sait faire from-scratch, mais cette fois en utilisant la librairie Java via IKVM. Pedagogie de la verification croisee (memes donnees, deux implementations) et de la frontiere de types (cell 23 : JObject + casts explicites, pas de marshalling magique).

Asymetrie reelle (mesuree, pas presupposee) : sur SetAF, EAF, Bipolar, le shade IKVM rend 0 type (cell 41). La tranche 2 ne peut donc PAS remplacer le jumeau tranche 1 sur ces trois frameworks ; la tranche 1 reste l’autorite pedagogique pour SetAF et EAF. Inversement, la tranche 1 n’a pas porte Bipolar du tout – il n’y a pas de parite Python/C# sur ce framework, juste un usage Python.

Verification cross-langage (c.170 G.1 firsthand, 2026-09-02) :

  • Python : cellules code Papermill-executees sur 2026-06-05 (9.95s, 0 erreur) ; 3 stubs exercices (WAF, bipolar, SetAF).
  • C# tranche 1 : cellules code .NET Interactive (cells 1-17, ADF/SetAF/EAF/VAF + Kleene + exemples), 0 erreur.
  • C# tranche 2 : cellules code (cells 18-42, section 7 IKVM) : cellules framework (Dung cell 28, Weighted cell 31, Social cell 34, ADF cell 37) chargeant le shade IKVM, + cellules setup/probe/lecture.
  • Total C# : cellules code (tranche 1 + tranche 2).
  • Exemples guides des deux notebooks utilisent des shapes differents (Python EAF = {b_e,e_e,d_e} 1 ext sur 5 args ; C# EAF = {a,b,c} 3 args avec reinstatement explicite) – la parite est sur l’algorithme (Kleene 3-valued + grounded fixed-point), pas sur l’exemple exact.

Ancrage prose <-> output (cette note ne tient pas en l’air) : les chiffres ci-dessus peuvent etre re-verifies par les commandes shell suivantes, executees a la racine du depot :

# Comptes cellules : Python notebook
python -c "import json; nb=json.load(open('MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-07a-Extended-Frameworks-Python.ipynb',encoding='utf-8')); print('Python total', len(nb['cells']), 'code', sum(1 for c in nb['cells'] if c['cell_type']=='code'))"
# Comptes cellules : C# jumeau
python -c "import json; nb=json.load(open('MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-07a-Extended-Frameworks-CSharp.ipynb',encoding='utf-8')); print('C# total', len(nb['cells']), 'code', sum(1 for c in nb['cells'] if c['cell_type']=='code'))"
# Tranche 2 IKVM : lister les cellules qui chargent le shade via IKVM
grep -lE 'IKVM|tweety-7a\.dll' MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-07a-Extended-Frameworks-CSharp.ipynb
# Asymetrie SetAF/EAF/Bipolar : la sonde 7.7.3 (cell 39) + lecture 7.7.4 (cell 41)
grep -nE 'absent|0 type' MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-07a-Extended-Frameworks-CSharp.ipynb

Ces commandes sont idempotentes : les relancer ne modifie rien et reproduit les memes chiffres tant que les notebooks sources ne bougent pas. Si l’un des chiffres devient faux apres une evolution, c’est cette note qu’il faut re-actualiser (pas re-livrer un nombre fige).

Voir aussi : MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-07a-Extended-Frameworks-CSharp.ipynb (jumeau C#), MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-5-Bipolar-Argumentation.ipynb (autre jumeau audite c.744), MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-06-Structured-Argumentation-Python.ipynb (autre jumeau audite c.743), MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-01-Setup-Python.ipynb (init JVM Tweety), MyIA.AI.Notebooks/SymbolicAI/Tweety/Tweety-7a-Extended-Frameworks_output.ipynb (output archive).

Issue : #14211. Précédent : #14143 (cote C#, jumeau tranche 2).


Résumé

Ce notebook a couvert les frameworks d’argumentation étendus:

Framework Extension Caractéristique principale Statut
ADF Conditions d’acceptation Formules propositionnelles par argument OK (solveur natif)
Evidential BAF Support ensembliste Arguments prima facie + support OK
Necessity BAF Support requis Tous les supportants nécessaires OK
WAF Poids sur attaques Seuils alpha/gamma OK
SAF Votes sociaux ISS (Iterated Schema Semantics) OK
SetAF Attaques collectives Ensemble -> argument OK
EAF Attaques sur attaques Argument -> (Arg -> Arg) OK
REAF Attaques récursives Multi-niveaux OK

Points clés à retenir

  1. ADF généralise Dung avec des solveurs SAT natifs (NativeMinisatSolver, NativeLingelingSolver, NativePicosatSolver)
  2. Les frameworks bipolaires modélisent naturellement les débats avec arguments “pour” et “contre”
  3. WAF permet de nuancer la force des attaques (utile en argumentation computationnelle)
  4. SAF intègre les opinions sociales (votes) dans l’évaluation des arguments
  5. SetAF capture les attaques collectives (plusieurs arguments ensemble pour invalider un tiers)
  6. EAF/REAF permettent des méta-arguments sur la validité des attaques elles-mêmes

Prochaines étapes

Le notebook suivant explore les sémantiques de classement (ranking-based) et l’argumentation probabiliste.


Navigation: ← Tweety-6-Structured-Argumentation | Index | Tweety-7b-Ranking-Probabilistic →

Retour au sommet