File size: 2,810 Bytes
cacd4d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
Base Genetic Operator Interface.

Defines the abstract interface for all genetic operators following
the Interface Segregation Principle (ISP) of SOLID.
"""

from abc import ABC, abstractmethod
from typing import List, Callable
import logging

logger = logging.getLogger(__name__)


class BaseGeneticOperator(ABC):
    """
    Abstract base class for genetic operators.
    
    All genetic operators (crossover, mutation, etc.) should inherit from this
    class and implement the __call__ method.
    
    Design Principles:
    - Single Responsibility: Each operator does one thing
    - Open/Closed: Extend via inheritance, don't modify
    - Liskov Substitution: Any operator works where base is expected
    - Interface Segregation: Minimal required interface
    - Dependency Inversion: Depend on abstractions (LLM callable)
    """
    
    @abstractmethod
    def __call__(self, *args, **kwargs) -> str:
        """
        Execute the genetic operation.
        
        Returns:
            str: New prompt generated by the operation
        """
        pass
    
    @abstractmethod
    def _build_prompt(self, *args, **kwargs) -> str:
        """
        Build the LLM prompt for this operation.
        
        Returns:
            str: Prompt to send to the LLM
        """
        pass


class BaseCrossoverOperator(BaseGeneticOperator):
    """
    Abstract base class for crossover operators.
    
    Crossover combines multiple parent prompts to create offspring
    that inherit good traits from both parents.
    """
    
    @abstractmethod
    def __call__(
        self,
        parents: List,  # List[PromptCandidate]
        target_fitness: float,
        llm: Callable[[str], str]
    ) -> str:
        """
        Combine parent prompts to create offspring.
        
        Args:
            parents: List of parent PromptCandidate objects
            target_fitness: Desired fitness for offspring
            llm: Language model callable
            
        Returns:
            str: Offspring prompt
        """
        pass


class BaseMutationOperator(BaseGeneticOperator):
    """
    Abstract base class for mutation operators.
    
    Mutation creates variations of a parent prompt to explore
    new regions of the search space.
    """
    
    @abstractmethod
    def __call__(
        self,
        parent,  # PromptCandidate
        population: List,  # List[PromptCandidate]
        llm: Callable[[str], str]
    ) -> str:
        """
        Mutate a parent prompt to create a variation.
        
        Args:
            parent: Parent PromptCandidate to mutate
            population: Current population for diversity guidance
            llm: Language model callable
            
        Returns:
            str: Mutated prompt
        """
        pass