Spaces:
Runtime error
Runtime error
File size: 5,505 Bytes
5ffcd9d 512509e 5ffcd9d 512509e 5ffcd9d 19ee5f6 5ffcd9d 19ee5f6 5ffcd9d 19ee5f6 5ffcd9d 19ee5f6 5ffcd9d 512509e 5ffcd9d 512509e | 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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | from sympy import Symbol, diff, simplify, sympify
from sympy.core.sympify import SympifyError
from app.clients.wolfram import WolframAlphaClient, WolframClientError
from app.schemas.numeric import NumericCheckItem, NumericCheckReport
from app.services.cas_arbitration import arbitrate_sympy_wolfram
def _clean_wolfram_plaintext_result(plaintext: str) -> str:
cleaned = plaintext.strip()
if "=" in cleaned:
cleaned = cleaned.split("=", 1)[1].strip()
return cleaned
def _extract_first_useful_wolfram_text(pods: list[object]) -> str | None:
for pod in pods:
title = getattr(pod, "title", "")
plaintext = getattr(pod, "plaintext", "")
if not plaintext:
continue
normalized_title = title.lower()
if normalized_title in {"derivative", "result", "alternate forms"}:
return _clean_wolfram_plaintext_result(str(plaintext))
if pods:
plaintext = getattr(pods[0], "plaintext", "")
if plaintext:
return _clean_wolfram_plaintext_result(str(plaintext))
return None
def validate_derivative(
expression: str,
expected_derivative: str,
variable: str = "x",
) -> NumericCheckItem:
x = Symbol(variable)
try:
parsed_expression = sympify(expression)
parsed_expected = sympify(expected_derivative)
computed = diff(parsed_expression, x)
is_valid = simplify(computed - parsed_expected) == 0
details = (
f"SymPy calcule d/d{variable}({expression}) = {computed}. "
f"Résultat attendu : {expected_derivative}."
)
if is_valid:
return NumericCheckItem(
check_type="derivative",
expression=expression,
expected=expected_derivative,
is_valid=True,
details=details,
sympy_status="ok",
sympy_result=str(computed),
wolfram_status="not_run",
wolfram_result=None,
cas_status="SYMPY_ONLY",
preferred_engine="sympy",
confidence_impact="neutral",
human_review_reason=None,
)
return NumericCheckItem(
check_type="derivative",
expression=expression,
expected=expected_derivative,
is_valid=False,
details=details,
sympy_status="ok",
sympy_result=str(computed),
wolfram_status="not_run",
wolfram_result=None,
cas_status="SYMPY_ONLY",
preferred_engine="sympy",
confidence_impact="decrease",
human_review_reason="sympy_contradicts_expected_derivative",
)
except (SympifyError, TypeError, ValueError) as exc:
return NumericCheckItem(
check_type="derivative",
expression=expression,
expected=expected_derivative,
is_valid=False,
details=f"Expression non exploitable par SymPy : {exc}",
sympy_status="failed",
sympy_result=None,
wolfram_status="not_run",
wolfram_result=None,
cas_status="NO_CAS_VALIDATION",
preferred_engine="none",
confidence_impact="decrease",
human_review_reason="sympy_unusable_expression",
)
async def validate_derivative_with_wolfram(
expression: str,
expected_derivative: str,
variable: str = "x",
) -> NumericCheckItem:
sympy_check = validate_derivative(expression, expected_derivative, variable)
query = f"derivative of {expression} with respect to {variable}"
try:
wolfram_response = await WolframAlphaClient().query(query)
except WolframClientError:
return arbitrate_sympy_wolfram(
sympy_check=sympy_check,
wolfram_result=None,
wolfram_success=False,
affects_score=True,
)
wolfram_result = _extract_first_useful_wolfram_text(wolfram_response.pods)
return arbitrate_sympy_wolfram(
sympy_check=sympy_check,
wolfram_result=wolfram_result,
wolfram_success=wolfram_response.success and bool(wolfram_result),
affects_score=True,
)
def run_numeric_checks_for_demo_answer(answer_text: str) -> NumericCheckReport:
normalized = answer_text.replace(" ", "")
checks: list[NumericCheckItem] = []
if "f'(x)=2x" in normalized or "f’(x)=2x" in normalized:
checks.append(validate_derivative("x**2", "2*x"))
contradicted = any(not check.is_valid for check in checks)
return NumericCheckReport(
checks=checks,
contradicted_by_numeric_check=contradicted,
needs_human_review=contradicted,
)
async def run_numeric_checks_for_demo_answer_with_wolfram(answer_text: str) -> NumericCheckReport:
normalized = answer_text.replace(" ", "")
checks: list[NumericCheckItem] = []
if "f'(x)=2x" in normalized or "f’(x)=2x" in normalized:
checks.append(await validate_derivative_with_wolfram("x**2", "2*x"))
contradicted = any(check.cas_status == "DISAGREEMENT" or not check.is_valid for check in checks)
needs_human_review = any(
check.cas_status == "DISAGREEMENT" or check.human_review_reason for check in checks
)
return NumericCheckReport(
checks=checks,
contradicted_by_numeric_check=contradicted,
needs_human_review=needs_human_review,
)
|