File size: 2,990 Bytes
1ed1403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import re
from typing import List, Dict, Any
from sympy import sympify, simplify, Eq, parse_expr

def extract_equations(text: str) -> List[str]:
    """Extracts mathematical equations or expressions from a reasoning step."""
    # Simplified extraction logic: finding equals signs or math blocks
    # In production, uses robust RegEx or specialized NLP parsing
    lines = text.split('\\n')
    equations = []
    for line in lines:
        if "=" in line and sum(c.isalpha() for c in line) < len(line) / 2:
            equations.append(line.strip())
    return equations

def check_logical_progression(step_n: str, step_n_plus_1: str) -> bool:
    """

    Implements the SymPy Validation function \\vartheta(r_{jl}).

    Checks if step (n+1) is a logically sound derivative of step (n).

    """
    eqs_n = extract_equations(step_n)
    eqs_n_plus_1 = extract_equations(step_n_plus_1)
    
    # If no math found natively, fallback to semantic/LLM truth (handled via Logic score)
    if not eqs_n or not eqs_n_plus_1:
        return True
        
    try:
        # Example validation: if step_n is 'a = b' and step is 'a + 1 = b + 1'
        # Simplifying via SymPy
        for eq1 in eqs_n:
            for eq2 in eqs_n_plus_1:
                e1_left, e1_right = eq1.split('=')
                e2_left, e2_right = eq2.split('=')
                
                # Verify equivalence: Left - Right should be 0
                expr1 = sympify(f"({e1_left}) - ({e1_right})")
                expr2 = sympify(f"({e2_left}) - ({e2_right})")
                
                # Check if they denote the same equality (simplified algebra)
                if simplify(expr1 - expr2) == 0:
                    return True
    except Exception:
        # Syntax error parsing SymPy, fall back to safe true 
        pass
        
    # By default, if we can't prove it false, we assume conditional true 
    # MVM2 specifically flags "1=2" paradoxes
    if "1 = 2" in step_n_plus_1 or "1=2" in step_n_plus_1:
        return False
        
    return True

def calculate_symbolic_score(reasoning_trace: List[str]) -> float:
    """

    Calculates V^{sym}_j based on the logical sequence of steps.

    Score drops linearly for every failed contiguous logic check.

    """
    if len(reasoning_trace) <= 1:
        return 1.0
        
    valid_transitions = 0
    total_transitions = len(reasoning_trace) - 1
    
    for i in range(total_transitions):
        is_valid = check_logical_progression(reasoning_trace[i], reasoning_trace[i+1])
        if is_valid:
            valid_transitions += 1
            
    v_sym = float(valid_transitions) / float(total_transitions)
    
    # If a critical hallucination is detected (e.g. proof of 1=2), heavily penalize
    for step in reasoning_trace:
        if "1 = 2" in step or "1=2" in step:
            v_sym = 0.0
            break
            
    return round(v_sym, 2)