TRIPLETS = [
TripletSitue("CTX-1", "contexte social", "On ferme ?", "réunion ouverte, aucun rôle assigné",
"fin de permanence, la personne tient la clé", ("relations", "contexte"),
("continuer",), ("continuer", "verrouiller"), ("attendre",), 0.15, 0.80,
"action", False),
TripletSitue("CTX-2", "contexte social", "Tu peux reprendre la main", "pair à pair, tâche inchangée",
"incident déclaré, rôle de pilote reconnu", ("relations", "contexte", "buts_communicatifs"),
("observer",), ("observer", "piloter"), ("escalader",), 0.20, 0.75,
"reprise", True),
TripletSitue("CTX-3", "contexte social", "Belle priorité", "retour informel sans artefact partagé",
"formulation identique sous tableau de tickets ordonné", ("contexte", "artefacts"),
("commenter",), ("commenter", "réordonner"), ("contester",), 0.10, 0.60,
"action", False),
TripletSitue("CTX-N", "contexte social", "On poursuit", "On continue", "On poursuit",
(), ("poursuivre",), ("poursuivre",), (), 0.40, 0.40, "silence", False),
TripletSitue("REG-1", "registre/indexicalité", "C'est carré", "registre littéral entre inconnus",
"registre complice après une réparation partagée", ("registres", "indexicaux", "relations"),
("valider",), ("valider", "clore_incident"), ("demander_preuve",), 0.25, 0.70,
"reprise", True),
TripletSitue("REG-2", "registre/indexicalité", "Nous, les experts", "auto-description institutionnelle",
"citation distanciée après un échec collectif", ("registres", "indexicaux", "contexte"),
("déclarer",), ("déclarer", "réviser_procédure"), ("défendre_statut",), 0.20, 0.65,
"action", True),
TripletSitue("REG-3", "registre/indexicalité", "Encore une victoire", "annonce littérale avant résultat",
"énoncé ironique après échec visible", ("registres", "indexicaux", "contexte"),
("annoncer",), ("annoncer", "ouvrir_postmortem"), ("minimiser",), 0.30, 0.80,
"refus explicite", True),
TripletSitue("REG-N", "registre/indexicalité", "We ship le patch", "Le patch part",
"We ship le patch", ("signes",), ("livrer",), ("livrer",), (), 0.55, 0.55,
"reprise", True),
TripletSitue("ASM-1", "assemblage sémiotique", "À toi", "phrase seule dans le fil",
"phrase + jeton de tour déplacé vers l'autre", ("artefacts", "relations", "contexte"),
("écouter",), ("écouter", "prendre_tour"), ("refuser_tour",), 0.10, 0.85,
"action", False),
TripletSitue("ASM-2", "assemblage sémiotique", "Même plan", "phrase sans support commun",
"phrase + carte annotée conjointement", ("artefacts", "relations", "buts_communicatifs"),
("acquiescer",), ("acquiescer", "éditer_carte"), ("proposer_carte",), 0.20, 0.75,
"action", False),
TripletSitue("ASM-N1", "assemblage sémiotique", "Nouveau : zorp", "mot absent", "mot affiché en marge",
("signes",), ("classer",), ("classer",), ("ignorer",), 0.25, 0.25,
"silence", True),
TripletSitue("ASM-N2", "assemblage sémiotique", "Cette phrase change tout", "phrase simple",
"phrase auto-référente sans reprise ni artefact", ("signes", "indexicaux"),
("lire",), ("lire",), ("contester",), 0.30, 0.30, "silence", True),
]
resultats_lt = pd.DataFrame(mesurer_triplet(t) for t in TRIPLETS)
negatifs_attendus = {"CTX-N", "REG-N", "ASM-N1", "ASM-N2"}
assert len(resultats_lt) == 12
assert resultats_lt.groupby("axe").size().eq(4).all()
assert set(resultats_lt.loc[~resultats_lt["coup_ontologique"], "id"]) == negatifs_attendus
assert (resultats_lt["coup_ontologique"] == ((resultats_lt["ΔA_t"] > 0) & (resultats_lt["P(R)"] > 0))).all()
print(resultats_lt.to_string(index=False))
print()
print("Bilan :", resultats_lt["coup_ontologique"].value_counts().rename(index={True: "positifs", False: "négatifs"}).to_dict())
print("Désaccords forme/uptake :", int((~resultats_lt["accord_forme_uptake"]).sum()), "/", len(resultats_lt))