35 lines
1.1 KiB
Python
35 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
from itertools import combinations
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from .models import SafetyPolicy, SwarmSolution
|
|
|
|
|
|
class VerificationReport(BaseModel):
|
|
passed: bool
|
|
violations: list[str] = Field(default_factory=list)
|
|
|
|
|
|
def verify_swarm_solution(solution: SwarmSolution, policy: SafetyPolicy) -> VerificationReport:
|
|
violations: list[str] = []
|
|
robots = solution.robots
|
|
|
|
for robot in robots:
|
|
if not policy.verify(robot.initial_pos, robot.current_pos):
|
|
violations.append(f"{robot.robot_id}: travel bound exceeded")
|
|
if robot.travel_distance > policy.energy_budget:
|
|
violations.append(f"{robot.robot_id}: energy budget exceeded")
|
|
|
|
for left, right in combinations(robots, 2):
|
|
if abs(left.current_pos - right.current_pos) < policy.min_separation:
|
|
violations.append(
|
|
f"{left.robot_id}/{right.robot_id}: separation below {policy.min_separation}"
|
|
)
|
|
|
|
if not solution.certificate.converged:
|
|
violations.append("solver did not converge")
|
|
|
|
return VerificationReport(passed=not violations, violations=violations)
|