# Solution complete — Exercice 1
from rdflib import Graph, Namespace, URIRef, Literal
from rdflib.namespace import RDF, RDFS, OWL, XSD
AIF = Namespace("http://www.arg.dundee.ac.uk/aif#") # noeuds AIF (ontologie Argumentum)
ARG = Namespace("https://www.argumentum.games/argumentum_fallacies.owl#")
AX = Namespace("http://example.org/aif-ext#") # pont + extension du coup
g_base = Graph()
g_base.bind("aif", AIF); g_base.bind("arg", ARG); g_base.bind("ax", AX)
g_base.bind("rdfs", RDFS); g_base.bind("owl", OWL)
# --- Pont : modele de noeuds AIF (classes reelles de l'ontologie Argumentum) ---
for c in ["I-node", "RA-node", "CA-node", "Inference_Scheme", "Conflict"]:
g_base.add((AIF[c], RDF.type, OWL.Class))
# Proprietes du modele de donnees : domaines/portees AIF + pont d'attaque
g_base.add((AIF.Premise, RDF.type, OWL.ObjectProperty))
g_base.add((AIF.Premise, RDFS.domain, AIF["RA-node"]))
g_base.add((AIF.Premise, RDFS.range, AIF["I-node"]))
g_base.add((AIF.Conclusion, RDF.type, OWL.ObjectProperty))
g_base.add((AIF.Conclusion, RDFS.domain, AIF["RA-node"]))
g_base.add((AIF.Conclusion, RDFS.range, AIF["I-node"]))
g_base.add((AIF.scheme, RDF.type, OWL.ObjectProperty))
g_base.add((AIF.scheme, RDFS.domain, AIF["RA-node"]))
g_base.add((AIF.scheme, RDFS.range, AIF.Inference_Scheme))
for p, dom in [(AX["from"], AIF["CA-node"]), (AX.to, AIF["CA-node"])]:
g_base.add((p, RDF.type, OWL.ObjectProperty))
g_base.add((p, RDFS.domain, dom))
# Schemes Walton materialises dans Argumentum (classes citees telles quelles)
for s in ["ExpertOpinion_Inference", "NegativeConsequences_Inference",
"Example_Inference", "Bias_Inference"]:
g_base.add((AIF[s], RDF.type, AIF.Inference_Scheme))
# --- Les I-nodes du debat ---
claims = {
"I1": "Les bibliothequaires recommandent l'acces numerique",
"I2": "La maintenance numerique coute cher",
"I3": "Le budget d'extension est serre",
"I4": "Le pilote papier-vers-numerique affiche 82% de satisfaction",
"I5": "Le pilote n'a interroge que des membres deja numeriques",
"I6": "La satisfaction du pilote n'est pas representative",
"C1": "Adopter la classe Ebook dans l'ontologie",
"C2": "Reporter l'extension de l'ontologie",
}
for nid, txt in claims.items():
g_base.add((AX[nid], RDF.type, AIF["I-node"]))
g_base.add((AX[nid], RDFS.label, Literal(txt, lang="fr")))
# --- Les RA-nodes (arguments) : premisses, conclusion, schema ---
def ra(g, nid, scheme_uri, premises, conclusion):
g.add((AX[nid], RDF.type, AIF["RA-node"]))
g.add((AX[nid], AIF.scheme, scheme_uri))
for p in premises:
g.add((AX[nid], AIF.Premise, AX[p]))
g.add((AX[nid], AIF.Conclusion, AX[conclusion]))
ra(g_base, "RA1", AIF.ExpertOpinion_Inference, ["I1"], "C1")
ra(g_base, "RA2", AIF.NegativeConsequences_Inference, ["I2", "I3"], "C2")
ra(g_base, "RA3", AIF.Example_Inference, ["I4"], "C1")
ra(g_base, "RA4", AIF.Bias_Inference, ["I5"], "I6")
# --- Les CA-nodes (attaques) : qui attaque quoi ---
def ca(g, nid, attacker, target):
g.add((AX[nid], RDF.type, AIF["CA-node"]))
g.add((AX[nid], AX["from"], AX[attacker]))
g.add((AX[nid], ARG.aifAttackedNode, AX[target]))
ca(g_base, "CA1", "RA2", "RA1") # undercut : l'argument de cout frappe le lien expertise -> adoption
ca(g_base, "CA2", "RA1", "RA2") # rebuttal : l'analyse des experts couvre deja les couts
ca(g_base, "CA3", "RA4", "I4") # undermine : le biais de selection atteint la premisse du pilote
print(f"Etat initial L_t : {len(g_base)} triplets")
print(f" I-nodes : 8 RA-nodes : 4 (RA1..RA4) CA-nodes : 3 (CA1..CA3)")
# --- Le coup eta : L_t -> L_{t+1} ---
g_ext = Graph()
for t in g_base:
g_ext.add(t)
# 1. Vocabulaire : nouveau schema + nouveau type de conflit
g_ext.add((AX.RepresentativeSample_Inference, RDF.type, AIF.Inference_Scheme))
g_ext.add((AX.RepresentativeSample_Inference, RDFS.subClassOf, AIF.Inference_Scheme))
g_ext.add((AX.SelectionBiasRebuttal_Conflict, RDF.type, AIF.Conflict))
g_ext.add((AX.SelectionBiasRebuttal_Conflict, RDFS.subClassOf, AIF.Conflict))
# 2. Instances : preuve corrigeant le biais, argument qui la porte, attaque qui retourne RA4
g_ext.add((AX["I7"], RDF.type, AIF["I-node"]))
g_ext.add((AX["I7"], RDFS.label, Literal("L'etude complementaire couvre tous les profils de membres", lang="fr")))
g_ext.add((AX["I8"], RDF.type, AIF["I-node"]))
g_ext.add((AX["I8"], RDFS.label, Literal("Le biais du pilote est corrige", lang="fr")))
# idiome Argumentum : le scheme est materialise comme classe, l'argument en est instance
ra(g_ext, "RA5", AX.RepresentativeSample_Inference, ["I7"], "I8") # schema du coup
g_ext.add((AX["RA5"], RDF.type, AX.RepresentativeSample_Inference))
g_ext.add((AX["CA4"], RDF.type, AIF["CA-node"]))
g_ext.add((AX["CA4"], RDF.type, AX.SelectionBiasRebuttal_Conflict)) # type de conflit du coup
g_ext.add((AX["CA4"], AX["from"], AX["RA5"]))
g_ext.add((AX["CA4"], ARG.aifAttackedNode, AX["I5"])) # undermine : la premisse du biais tombe
# --- Le diff de triplets ---
diff_set = set(g_ext) - set(g_base)
print(f"\nLe coup ajoute {len(diff_set)} triplets :")
print("-" * 60)
diff_list = sorted(diff_set, key=lambda t: (str(t[0]), str(t[1]), str(t[2])))
for s, p, o in diff_list:
print(f" {s.n3(g_ext.namespace_manager)} {p.n3(g_ext.namespace_manager)} {o.n3(g_ext.namespace_manager)} .")