File size: 2,193 Bytes
2e818da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from __future__ import annotations

import math

from app.schemas.visual_lesson import DifferentialEquationSpec
from app.services.differential_equation_compiler import DifferentialEquationCompiler


class DifferentialEquationValidationError(ValueError):
    pass


class DifferentialEquationValidator:
    def __init__(self, compiler: DifferentialEquationCompiler) -> None:
        self.compiler = compiler

    def validate(self, spec: DifferentialEquationSpec) -> None:
        if spec.sample_count != self.compiler.SAMPLE_COUNT:
            raise DifferentialEquationValidationError("Differential-equation sample count is unsupported")
        if not math.isfinite(spec.t_start) or not math.isfinite(spec.t_end) or spec.t_end <= spec.t_start:
            raise DifferentialEquationValidationError("Differential-equation time bounds are invalid")
        required_views = {"trajectory", "phase_portrait"} if spec.family == "damped_oscillator" else {"trajectory", "direction_field"}
        if not required_views <= set(spec.enabled_views):
            raise DifferentialEquationValidationError("The required visual views are missing")
        claim_ids = {claim.claim_id for claim in spec.evidence_claims}
        if "ode-initial-value" not in claim_ids:
            raise DifferentialEquationValidationError("The visualization is missing its initial-value evidence claim")
        if spec.family != "damped_oscillator" and "ode-direction-field" not in claim_ids:
            raise DifferentialEquationValidationError("The visualization is missing its direction-field evidence claim")
        if spec.family == "logistic" and "ode-logistic" not in claim_ids:
            raise DifferentialEquationValidationError("The logistic visualization is missing its model claim")
        if spec.family == "damped_oscillator" and "ode-numerical-method" not in claim_ids:
            raise DifferentialEquationValidationError("The oscillator visualization is missing its numerical-method disclosure")
        compiled = self.compiler.compile_spec(spec)
        if not compiled.assertions_passed:
            raise DifferentialEquationValidationError("Differential-equation compiler assertions failed")