---
name: overeni-prikladu
description: Ověří správnost matematických příkladů jejich převedením do Pythonu (sympy) a spuštěním v Dockeru. Použij když uživatel chce ověřit, zkontrolovat, validovat nebo verifikovat příklady, řešení nebo výsledky.
---

# Ověření příkladů

## Prerekvizity

Docker nainstalovaný a běžící. Při prvním spuštění postav image:

```bash
docker build -t math-verify .cursor/skills/overeni-prikladu/
```

## Postup

1. Přečti soubor s příklady
2. Pro každý příklad napiš do `verify_{nahodne_cislo}_{skupina}_{soubor}.py` sympy kód, který:
   - Vypočte výsledek ze zadání a porovná s uvedeným řešením → **OK/FAIL**
   - Trasuje mezivýpočty a kontroluje jejich velikost → **CLEAN/WARN**
3. Spusť:
   ```bash
   docker run --rm -v "$(pwd):/work" math-verify python verify_{nahodne_cislo}_{skupina}_{soubor}.py
   ```
4. Vyhodnoť výstup — pro každý příklad dvojice: správnost + řešitelnost na papíře
5. Smaž `verify_{nahodne_cislo}_{skupina}_{soubor}.py`
6. Pokud něco selže nebo varuje, uveď ID příkladu a detail

## Struktura verify_{nahodne_cislo}_{skupina}_{soubor}.py

```python
from sympy import *

x, y, z, n, k = symbols('x y z n k')

checks = []

# C1: 2^3 · 2^5
checks.append(("C1", 2**3 * 2**5, 256))

# A1: slovní úloha → soustava
sol = solve([x + y - 56, x - y - 18], [x, y])
checks.append(("A1", (sol[x], sol[y]), (37, 19)))

failed = 0
for label, computed, expected in checks:
    ok = simplify(Matrix([computed]) - Matrix([expected])).is_zero_matrix \
         if isinstance(computed, tuple) \
         else simplify(computed - expected) == 0
    status = "OK" if ok else "FAIL"
    if not ok:
        failed += 1
    print(f"  {status}  {label}: got {computed}, expected {expected}")

print(f"\n{'ALL PASSED' if failed == 0 else f'{failed} FAILED'}")
```

## Kontrola řešitelnosti na papíře

Kromě správnosti ověř, že mezivýpočty jsou zvládnutelné bez kalkulačky. Pro každý příklad vypiš `CLEAN` nebo `WARN`.

### Prahy

| Typ hodnoty | Práh | Příklad překročení |
|---|---|---|
| Celé číslo (mezivýpočet) | \|n\| ≤ 200 | násobení řádku dá 1350 |
| Jmenovatel zlomku | \|q\| ≤ 12 | výsledek x = 17/13 |
| Čitatel zlomku | \|p\| ≤ 200 | výsledek x = 247/3 |

Prahy jsou orientační — slovní úlohy s penězi/vzdálenostmi mívají větší čísla přirozeně. WARN neznamená chybu, jen upozornění k ruční kontrole.

### Soustavy 2×2: simulace eliminace

Pro soustavu `a·x + b·y = e`, `c·x + d·y = f` trasuj postup, který žák dělá na papíře:

```python
from math import gcd as _gcd

THRESHOLD_INT = 200
THRESHOLD_DENOM = 12

def lcm(a, b):
    return abs(a * b) // _gcd(abs(a), abs(b))

def trace_elimination(label, a, b, e, c, d, f):
    vals = {}
    L = lcm(int(abs(a)), int(abs(c)))
    m1, m2 = L // abs(int(a)), L // abs(int(c))

    vals['LCM koeficientů u x'] = L
    vals[f'ř.1 × {m1}: koef y'] = m1 * b
    vals[f'ř.1 × {m1}: pravá str.'] = m1 * e
    vals[f'ř.2 × {m2}: koef y'] = m2 * d
    vals[f'ř.2 × {m2}: pravá str.'] = m2 * f

    sign = -1 if (a > 0) == (c > 0) else 1
    op = "odečtení" if sign == -1 else "sečtení"
    coeff_y = m1 * b + sign * m2 * d
    rhs = m1 * e + sign * m2 * f
    vals[f'{op}: koef y'] = coeff_y
    vals[f'{op}: pravá str.'] = rhs

    y_val = Rational(rhs, coeff_y)
    vals['y'] = y_val
    back = e - b * y_val
    vals['dosazení: pravá str.'] = back
    x_val = Rational(back, a)
    vals['x'] = x_val

    warnings = []
    for desc, v in vals.items():
        r = Rational(v)
        if r.is_Integer and abs(r) > THRESHOLD_INT:
            warnings.append(f"    {desc} = {v}")
        elif not r.is_Integer and (abs(r.p) > THRESHOLD_INT or abs(r.q) > THRESHOLD_DENOM):
            warnings.append(f"    {desc} = {v}")

    return (x_val, y_val), warnings
```

### Ostatní typy příkladů

- **Výrazy (zjednodušování, mocniny)**: zkontroluj, že žádný mezivýsledek nemá více než 4 cifry a odmocniny jsou z rozumných čísel (radicand ≤ 1000)
- **Rovnice**: po každém kroku (roznásobení, přesun) zkontroluj koeficienty
- **Pokud nejde trasovat**: přeskoč kontrolu mezivýpočtů, vypiš jen správnost

### Výstupní formát

```
  OK  CLEAN  A1
  OK  WARN   A4
    ř.2 × 1: pravá str. = 1350
    odečtení: pravá str. = -1250
  FAIL CLEAN  A6
    got (7, 2), expected (8, 3)

Správnost: 7/8
Řešitelnost na papíře: 7/8 CLEAN
```

## Pravidla převodu

- `Rational` pro zlomky — nikdy Python `/` mezi celými čísly
- `sqrt()` pro odmocniny, `cbrt()` pro třetí odmocninu
- Rovnice: `Eq(lhs, rhs)` + `solve()`
- Soustavy: `solve([eq1, eq2], [x, y])`
- Zjednodušování: `simplify()`, `expand()`, `factor()`
- Goniometrie: `sin`, `cos`, `tan`, úhly v radiánech (`pi/6`, `pi/4`, `pi/3`)
- Porovnání vždy přes `simplify(a - b) == 0`, nikdy `==` přímo
- Slovní úlohy: přelož podmínky zadání do rovnic, vyřeš, porovnej numerické výsledky
- Pokud příklad nelze převést do kódu (důkazové, "rozhodni", "zdůvodni"), přeskoč ho a vypiš `SKIP  ID: důvod`

## Příklady, které nelze verifikovat

Některé typy úloh není možné automaticky ověřit — přeskoč je s `SKIP`:

- "Rozhodni, zda..." (logický argument)
- "Zdůvodni, proč..." (slovní vysvětlení)
- "Načrtni graf..." (grafický výstup)
- Úlohy kde řešení obsahuje jen slovní postup bez numerického výsledku
