"""Base constraint classes.""" from dataclasses import dataclass, field from typing import List, Set, Dict, Optional, Any from enum import Enum class ConstraintType(Enum): """Types of constraints in the scheduling system.""" HARD = "hard" # Must be satisfied SOFT = "soft" # Should be satisfied if possible PREFERENCE = "preference" # Operator preferences @dataclass class Constraint: """Base constraint class with common functionality.""" constraint_id: str constraint_type: ConstraintType description: str severity: int = 0 # Higher = more important enabled: bool = True metadata: Dict[str, Any] = field(default_factory=dict) def is_satisfied(self, context: Dict[str, Any]) -> bool: """Check if constraint is satisfied in given context.""" # Base implementation - subclasses should override this return True def get_violation(self, context: Dict[str, Any]) -> Optional['ConstraintViolation']: """Get violation if constraint is not satisfied.""" if self.is_satisfied(context): return None return ConstraintViolation( constraint_id=self.constraint_id, constraint_type=self.constraint_type, description=self.description, severity=self.severity, context=context ) @dataclass class ConstraintViolation: """Represents a constraint violation.""" constraint_id: str constraint_type: ConstraintType description: str severity: int context: Dict[str, Any] violation_message: str = field(init=False) def __post_init__(self): self.violation_message = f"{self.constraint_id}: {self.description}" def to_dict(self) -> Dict[str, Any]: """Convert violation to dictionary.""" return { 'constraint_id': self.constraint_id, 'constraint_type': self.constraint_type.value, 'description': self.description, 'severity': self.severity, 'context': self.context, 'violation_message': self.violation_message }