"""Constraints package.""" from dataclasses import dataclass from typing import List, Dict, Any, Optional, Union from constraints.base_constraint import Constraint, ConstraintViolation, ConstraintType from constraints.hard_constraints import ( SkillRequirementConstraint, ShiftCoverageConstraint, MaxWorkTimeConstraint, DepartmentAssignmentConstraint, MinCoverageConstraint, ConflictPreventionConstraint, create_hard_constraints ) from constraints.soft_constraints import ( OperatorPreferenceConstraint, DayAvailabilityConstraint, WorkBalanceConstraint, ContinuityPreference, SeniorityPriorityConstraint, create_soft_constraints ) @dataclass class ConstraintSet: """Container for all constraints (hard and soft).""" hard_constraints: List[Constraint] soft_constraints: List[Constraint] scenario: Dict[str, Any] def validate(self, context: Dict[str, Any]) -> List[ConstraintViolation]: """Validate all constraints and return violations.""" violations = [] # Check hard constraints for constraint in self.hard_constraints: if constraint.enabled: violation = constraint.get_violation(context) if violation: violations.append(violation) # Check soft constraints (only warn, don't fail) for constraint in self.soft_constraints: if constraint.enabled: violation = constraint.get_violation(context) if violation: violations.append(violation) return violations def get_enabled_hard_constraints(self) -> List[Constraint]: """Get all enabled hard constraints.""" return [c for c in self.hard_constraints if c.enabled] def get_enabled_soft_constraints(self) -> List[Constraint]: """Get all enabled soft constraints.""" return [c for c in self.soft_constraints if c.enabled] def get_disabled_constraints(self) -> List[Constraint]: """Get all disabled constraints.""" return [c for c in self.hard_constraints + self.soft_constraints if not c.enabled] def enable_constraint(self, constraint_id: str) -> bool: """Enable a constraint by ID.""" for constraint in self.hard_constraints + self.soft_constraints: if constraint.constraint_id == constraint_id: constraint.enabled = True return True return False def disable_constraint(self, constraint_id: str) -> bool: """Disable a constraint by ID.""" for constraint in self.hard_constraints + self.soft_constraints: if constraint.constraint_id == constraint_id: constraint.enabled = False return True return False def clear_violations(self, context: Dict[str, Any]) -> bool: """Check if all violations can be cleared in context.""" violations = self.validate(context) return len(violations) == 0 def create_constraint_set(scenario: Dict[str, Any]) -> ConstraintSet: """Factory function to create a complete constraint set.""" hard = create_hard_constraints(scenario) soft = create_soft_constraints(scenario) return ConstraintSet( hard_constraints=hard, soft_constraints=soft, scenario=scenario )