File size: 5,986 Bytes
98c2b46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# argument_visualizer.py (V2/V3 - Adım 3.1: Düşük Eşik Denemesi)
import networkx as nx
from typing import List, Dict
import data_models
from rich.console import Console
import textwrap
import torch
import torch.nn.functional as F

console = Console()

# Anlamsal Benzerlik Eşiği DÜŞÜRÜLDÜ!
LINKING_SIMILARITY_THRESHOLD = 0.55 # Önceki 0.65 idi, şimdi 0.55 deneyelim

# --- Yardımcı Fonksiyon: Benzerlik Hesaplama (Aynı) ---
def calculate_similarity(emb1: torch.Tensor | None, emb2: torch.Tensor | None) -> float | None:
     if emb1 is None or emb2 is None: return None
     emb1 = emb1.cpu(); emb2 = emb2.cpu()
     if emb1.dim() == 1: emb1 = emb1.unsqueeze(0)
     if emb2.dim() == 1: emb2 = emb2.unsqueeze(0)
     try: return F.cosine_similarity(emb1, emb2).item()
     except Exception as e: console.print(f"[yellow]Warn: Cosine similarity failed: {e}[/yellow]"); return None

# --- Ana Grafik Oluşturma Fonksiyonu (Aynı) ---
def build_argument_graph(

    components: List[data_models.ArgumentComponent],

    sentence_embeddings: List[torch.Tensor | None]

) -> nx.DiGraph | None:
    # ... (Fonksiyonun geri kalanı bir önceki mesajdakiyle aynı)...
    if not components: return None
    G = nx.DiGraph()
    claims = []; premises = []
    for i, comp in enumerate(components):
        node_id = f"{comp.component_type[0]}{i+1}"
        conf_str = f" (Conf: {comp.confidence:.2f})" if comp.confidence is not None else ""
        node_label = f"\"{textwrap.shorten(comp.text, width=35, placeholder='...')}\"{conf_str}"
        node_shape = "()" if comp.component_type == "Claim" else "[]"
        G.add_node(node_id, label=node_label, type=comp.component_type, shape=node_shape, component_index=i, sentence_index=comp.sentence_index)
        if comp.component_type == "Claim": claims.append((i, node_id, comp.sentence_index))
        else: premises.append((i, node_id, comp.sentence_index))

    if not claims or not premises:
        console.print(" -> Argument graph requires at least one claim and one premise to show structure.", style="dim")
        return G

    edges_added = 0
    for p_comp_idx, p_node_id, p_sent_idx in premises:
        if not (0 <= p_sent_idx < len(sentence_embeddings)): continue
        premise_embedding = sentence_embeddings[p_sent_idx]
        if premise_embedding is None: continue
        for c_comp_idx, c_node_id, c_sent_idx in claims:
             if not (0 <= c_sent_idx < len(sentence_embeddings)): continue
             claim_embedding = sentence_embeddings[c_sent_idx]
             if claim_embedding is None: continue
             similarity = calculate_similarity(premise_embedding, claim_embedding)
             if similarity is not None and similarity >= LINKING_SIMILARITY_THRESHOLD: # Eşik kontrolü
                  console.print(f"   -> Linking {p_node_id} to {c_node_id} (Similarity: {similarity:.2f})", style="dim")
                  G.add_edge(p_node_id, c_node_id, relation="supports", similarity=similarity)
                  edges_added += 1
    if edges_added == 0:
         console.print(f" -> Could not link any premises to claims based on similarity threshold ({LINKING_SIMILARITY_THRESHOLD}).", style="dim")
    console.print(f" -> Built argument graph with {G.number_of_nodes()} nodes and {G.number_of_edges()} edges (Semantic Linking).", style="dim")
    return G


# Grafik Formatlama Fonksiyonu (Aynı)
def format_graph_text(graph: nx.DiGraph | None) -> str:
    # ... (Fonksiyonun içeriği öncekiyle aynı) ...
    if graph is None: return "  Argument graph could not be built."
    if graph.number_of_nodes() == 0: return "  No argument components identified to build a graph."
    output_lines = ["  Argument Structure (Linked by Semantic Similarity):"]
    isolated_nodes = [node for node, degree in graph.degree() if degree == 0 and graph.in_degree(node)==0 and graph.out_degree(node)==0 ]
    connected_nodes = set()
    if graph.number_of_edges() == 0:
        if not isolated_nodes: output_lines.append("  No argument structure links could be determined.")
    else:
        output_lines.append("  Detected Links (Premise --Supports (Similarity)--> Claim):")
        for u, v, data in graph.edges(data=True):
            connected_nodes.add(u); connected_nodes.add(v)
            u_data = graph.nodes[u]; v_data = graph.nodes[v]
            u_shape = u_data.get('shape', '[]'); v_shape = v_data.get('shape', '()')
            u_label = u_data.get('label', u); v_label = v_data.get('label', v)
            similarity = data.get('similarity')
            sim_str = f"(Sim: {similarity:.2f})" if similarity is not None else ""
            output_lines.append(f"    {u_shape[0]}{u}{u_shape[1]}: {u_label}")
            output_lines.append(f"      {' ' * len(u)} --Supports {sim_str}--> {v_shape[0]}{v}{v_shape[1]}: {v_label}")
            output_lines.append("")

    really_isolated = set(isolated_nodes) # Tüm izoleler
    if really_isolated:
         # Eğer kenar varsa ve izole düğüm varsa başlık ekle
         if graph.number_of_edges() > 0:
             output_lines.append("  Nodes without determined links:")
         # Kenar yoksa zaten yukarıda başlık vardı
         elif not isolated_nodes and graph.number_of_edges() == 0 : # Hata durumu, yukarıda handle edildi
             pass
         elif isolated_nodes and graph.number_of_edges() == 0: # Sadece izole düğümler varsa
              output_lines.append("  Nodes (No links determined):")


         for node_id in sorted(list(really_isolated)):
              data = graph.nodes[node_id]
              shape = data.get('shape', '??')
              label = data.get('label', node_id)
              output_lines.append(f"    {shape[0]}{node_id}{shape[1]}: {label}")

    output_lines.append(f"  [dim](Links based on similarity >= {LINKING_SIMILARITY_THRESHOLD})[/dim]")
    return "\n".join(output_lines)