Mutations
Executor
hgp_lib.mutations.mutation_executor.MutationExecutor
Coordinates literal and operator mutations across a collection of Rule trees.
The executor samples how many nodes of every rule should be mutated based on mutation_p,
picks concrete nodes uniformly at random, and retries failed mutations up to num_tries
times when a check_valid predicate is provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
literal_mutations
|
Tuple[Mutation, ...]
|
Mutations that can be applied to literal nodes. The sequence must be non-empty and
each entry must declare |
required |
operator_mutations
|
Tuple[Mutation, ...]
|
Mutations that can be applied to operator nodes. The sequence must be non-empty and
each entry must declare |
required |
mutation_p
|
float
|
Probability of mutating each node inside a rule. Default: |
0.1
|
check_valid
|
Callable[[Rule], bool] | None
|
Optional validator executed after every successful mutation. When supplied, the
mutated rule is only kept if the predicate returns |
None
|
num_tries
|
int
|
Maximum number of attempts per node in case mutations raise |
1
|
operator_p
|
float
|
Probability of selecting an operator node (vs. a literal) when choosing a mutation
point in the rule tree. Must be in [0.0, 1.0]. Default: |
0.5
|
Examples:
>>> import random
>>> import numpy as np
>>> from hgp_lib.mutations import MutationExecutor, NegateMutation
>>> from hgp_lib.rules import Literal, And
>>> random.seed(1); np.random.seed(0)
>>> executor = MutationExecutor(
... literal_mutations=[NegateMutation()],
... operator_mutations=[NegateMutation()],
... mutation_p=1.0,
... operator_p=0.5,
... )
>>> rules = [Literal(value=0), And([Literal(value=0), Literal(value=1)])]
>>> executor.apply(rules)
>>> str(rules[0])
'~0'
>>> str(rules[1])
'~And(~0, ~1)'
Source code in hgp_lib\mutations\mutation_executor.py
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
apply(rules)
Mutates the provided list of rules in place.
In the event of a mutation failure, the original rule is kept in place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rules
|
List[Rule]
|
The mutable collection of rules that will be potentially replaced by mutated
versions depending on |
required |
Examples:
>>> import random
>>> import numpy as np
>>> from hgp_lib.mutations import MutationExecutor, NegateMutation
>>> from hgp_lib.rules import Literal
>>> random.seed(1); np.random.seed(1)
>>> executor = MutationExecutor(
... literal_mutations=[NegateMutation()],
... operator_mutations=[NegateMutation()],
... mutation_p=1.0,
... )
>>> rules = [Literal(value=0)]
>>> executor.apply(rules)
>>> str(rules[0])
'~0'
Source code in hgp_lib\mutations\mutation_executor.py
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 109 110 111 112 | |
Factory
hgp_lib.mutations.mutation_factory.MutationExecutorFactory
Factory for creating MutationExecutor instances.
Stores configuration-time parameters (mutation_p, num_tries) and defers
data-dependent construction to create. Override create_literal_mutations
and/or create_operator_mutations to customize which mutations are used.
Attributes:
| Name | Type | Description |
|---|---|---|
mutation_p |
float
|
Per-node mutation probability. Default: |
num_tries |
int
|
Maximum number of attempts per mutation node. Must be |
operator_p |
float
|
Probability of selecting an operator node (vs. a literal)
when choosing a mutation point in the rule tree. Must be in [0.0, 1.0].
Default: |
operator_types |
Sequence[Type[Rule]]
|
Sequence of operator classes
(e.g., |
Examples:
>>> from hgp_lib.mutations import MutationExecutorFactory
>>> factory = MutationExecutorFactory(mutation_p=0.05)
>>> factory.mutation_p
0.05
>>> factory.num_tries
1
Subclass to use custom mutations:
>>> from hgp_lib.mutations import MutationExecutorFactory, NegateMutation
>>> class NegateOnlyFactory(MutationExecutorFactory):
... def create_literal_mutations(self, num_literals):
... return (NegateMutation(),)
... def create_operator_mutations(self, num_literals):
... return (NegateMutation(),)
>>> factory = NegateOnlyFactory(mutation_p=1.0)
>>> executor = factory.create(num_literals=4)
>>> len(executor.literal_mutations)
1
Source code in hgp_lib\mutations\mutation_factory.py
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
create_literal_mutations(num_literals)
Create the set of standard literal-level mutations. Override this method to use custom literal mutations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_literals
|
int
|
Total number of available literal values. Must be greater than |
required |
Returns:
| Type | Description |
|---|---|
Tuple[Mutation, ...]
|
Tuple[Mutation, ...]: Literal mutations for the executor. |
Examples:
>>> from hgp_lib.mutations import MutationExecutorFactory
>>> from hgp_lib.rules import And, Or
>>> mutations = MutationExecutorFactory().create_literal_mutations(num_literals=4)
>>> [type(mutation).__name__ for mutation in mutations]
['DeleteMutation', 'NegateMutation', 'ReplaceLiteral', 'PromoteLiteral']
Source code in hgp_lib\mutations\mutation_factory.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
create_operator_mutations(num_literals)
Create the set of standard operator-level mutations. Override this method to use custom operator mutations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_literals
|
int
|
Total number of available literal values. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Mutation
|
Tuple[Mutation, ...]: Operator mutations for the executor. |
|
Examples |
...
|
|
Tuple[Mutation, ...]
|
|
|
Tuple[Mutation, ...]
|
|
|
Tuple[Mutation, ...]
|
|
|
Tuple[Mutation, ...]
|
|
|
Tuple[Mutation, ...]
|
['DeleteMutation', 'NegateMutation', 'RemoveIntermediateOperator', 'ReplaceOperator', 'AddLiteral'] |
Source code in hgp_lib\mutations\mutation_factory.py
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
create(num_literals, check_valid=None)
Create a MutationExecutor with the configured mutations and parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_literals
|
int
|
Total number of available literal values. |
required |
check_valid
|
Callable[[Rule], bool] | None
|
Optional rule validator.
Default: |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
MutationExecutor |
MutationExecutor
|
Configured mutation executor. |
Source code in hgp_lib\mutations\mutation_factory.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
Literal Mutations
hgp_lib.mutations.literal_mutations.DeleteMutation
Bases: Mutation
Remove a Rule node from its parent operator in-place.
Applicable to both literal and operator nodes. The mutation has two modes depending on the parent's subrule count:
- Parent has 3+ subrules: the target node is simply removed from the parent's subrule list.
- Parent has exactly 2 subrules (collapse): the remaining sibling is
appended to the grandparent's subrule list and the now-redundant parent
operator is removed from the grandparent. This requires a grandparent to
exist; if there is none, a
MutationErroris raised.
A MutationError is also raised when the target node is the root of the
tree (has no parent).
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
Examples:
Simple removal (parent has 3 subrules):
>>> from hgp_lib.mutations import DeleteMutation
>>> from hgp_lib.rules import And, Literal
>>> parent = And([Literal(value=0), Literal(value=1), Literal(value=2)])
>>> mutation = DeleteMutation()
>>> mutation.apply(parent.subrules[1])
>>> parent
And(0, 2)
Collapse (parent has 2 subrules — sibling is appended to grandparent):
>>> from hgp_lib.rules import Or
>>> root = Or([
... Literal(value=0),
... And([Literal(value=1), Literal(value=2)]),
... ])
>>> mutation.apply(root.subrules[1].subrules[0])
>>> root
Or(0, 2)
Source code in hgp_lib\mutations\literal_mutations.py
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 109 110 111 112 113 114 115 116 117 118 119 120 | |
apply(rule)
Delete rule from its parent's subrule list in-place.
When the parent has more than two subrules, the target is simply removed. When the parent has exactly two subrules, the remaining sibling is appended to the grandparent's subrule list and the parent operator is removed from the grandparent (collapse).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The rule node to delete. |
required |
Raises:
| Type | Description |
|---|---|
MutationError
|
If |
Examples:
Simple removal:
>>> from hgp_lib.mutations import DeleteMutation
>>> from hgp_lib.rules import Or, Literal
>>> parent = Or([Literal(value=1), Literal(value=2), Literal(value=3)])
>>> DeleteMutation().apply(parent.subrules[2])
>>> parent
Or(1, 2)
Collapse — the inner And is removed and its surviving child is appended to the root:
>>> from hgp_lib.rules import And
>>> root = Or([
... Literal(value=0),
... And([Literal(value=1), Literal(value=2)]),
... Literal(value=3),
... ])
>>> DeleteMutation().apply(root.subrules[1].subrules[1])
>>> root
Or(0, 3, 1)
Source code in hgp_lib\mutations\literal_mutations.py
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 109 110 111 112 113 114 115 116 117 118 119 120 | |
hgp_lib.mutations.literal_mutations.NegateMutation
Bases: Mutation
The NegateMutation inverts inplace the logical negation flag of a given Rule. It is applicable to both literals
and operator nodes.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
Examples:
>>> from hgp_lib.mutations import NegateMutation
>>> from hgp_lib.rules import Literal, And
>>> mutation = NegateMutation()
>>> rule = Literal(value=1)
>>> mutation.apply(rule)
>>> rule
~1
>>> mutation.apply(rule)
>>> rule
1
>>> rule = And([Literal(value=0), Literal(value=1)])
>>> mutation.apply(rule)
>>> rule
~And(0, 1)
Source code in hgp_lib\mutations\literal_mutations.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
apply(rule)
Applies an inplace negation mutation to the given Rule. Toggles the rule's negated flag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The rule node whose negation flag will be flipped. |
required |
Examples:
>>> from hgp_lib.mutations import NegateMutation
>>> from hgp_lib.rules import Literal
>>> rule = Literal(value=0)
>>> mutation = NegateMutation()
>>> mutation.apply(rule)
>>> rule
~0
>>> mutation.apply(rule)
>>> rule
0
Source code in hgp_lib\mutations\literal_mutations.py
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
hgp_lib.mutations.literal_mutations.ReplaceLiteral
Bases: Mutation
The ReplaceLiteral mutation replaces the value of a literal Rule with a different random literal index.
It ensures that the new literal value differs from the current one. This mutation is only applicable to literal
nodes and never to operator nodes.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
num_literals |
int
|
The total number of possible literal values. Must be greater than |
Notes
- The new literal value is chosen uniformly at random from the range
[0, num_literals). - If the randomly chosen value equals the current literal's value, it is incremented modulo
num_literalsto guarantee a change. - The mutation operates inplace and modifies only the literal's
value.
Examples:
>>> from hgp_lib.mutations import ReplaceLiteral
>>> from hgp_lib.rules import Literal
>>> mutation = ReplaceLiteral(num_literals=2)
>>> rule = Literal(value=0)
>>> mutation.apply(rule)
>>> rule
1
Source code in hgp_lib\mutations\literal_mutations.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
apply(rule)
Applies an inplace literal replacement mutation to the given Rule. Randomly assigns a new literal value
different from the current one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The literal rule whose value will be replaced. |
required |
Examples:
>>> from hgp_lib.mutations import ReplaceLiteral
>>> from hgp_lib.rules import Literal
>>> mutation = ReplaceLiteral(num_literals=4)
>>> rule = Literal(value=1)
>>> mutation.apply(rule)
>>> rule.value != 1
True
Source code in hgp_lib\mutations\literal_mutations.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
hgp_lib.mutations.literal_mutations.PromoteLiteral
Bases: Mutation
The PromoteLiteral mutation converts a literal Rule into an operator node (i.e. And, Or) by promoting it
and attaching two literal children: one representing the old literal and another newly generated literal.
This mutation increases the structural complexity of the rule tree.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
num_literals |
int
|
The total number of possible literal values. Must be greater than |
operator_types |
Tuple[Type[Rule]]
|
Tuple of operator classes (e.g., |
Notes
- The literal is transformed inplace into an operator node by changing its class (
__class__). - Two new subrules are attached:
- The original literal (same value and negation),
- A new literal with a randomly chosen value different from the original.
- Random negation flags are assigned independently to the new operator and the new literal.
- The
valueattribute of the promoted node is cleared (None) since it becomes an operator.
Examples:
>>> from hgp_lib.mutations import PromoteLiteral
>>> from hgp_lib.rules import Literal, And, Or
>>> mutation = PromoteLiteral(num_literals=4)
>>> rule = Literal(value=1, negated=False)
>>> mutation.apply(rule)
>>> len(rule)
3
>>> isinstance(rule, Or) or isinstance(rule, And)
True
>>> rule.subrules[0]
1
Source code in hgp_lib\mutations\literal_mutations.py
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
apply(rule)
Promotes a literal node into a randomly chosen operator (And or Or), creating two new literal subrules:
one representing the old literal and another newly generated literal with a different value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The literal rule to promote. |
required |
Notes
- The transformation occurs inplace by reassigning
rule.__class__. - The mutation randomizes negation for both the operator and the new literal.
Examples:
>>> from hgp_lib.mutations import PromoteLiteral
>>> from hgp_lib.rules import Literal
>>> mutation = PromoteLiteral(num_literals=3)
>>> rule = Literal(value=0, negated=True)
>>> mutation.apply(rule)
>>> len(rule)
3
>>> isinstance(rule, Or) or isinstance(rule, And)
True
>>> rule.subrules[0]
~0
Source code in hgp_lib\mutations\literal_mutations.py
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
Operator Mutations
hgp_lib.mutations.operator_mutations.RemoveIntermediateOperator
Bases: Mutation
The RemoveIntermediateOperator mutation removes an intermediate operator node (e.g., And, Or) and promotes its
subrules to the operator's parent, flattening the rule tree structure.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
Notes
- The mutation raises a
MutationErrorif the operator has no parent (i.e., it is the root of the tree). - All child subrules of the removed operator are reattached directly to the parent.
- The parent's subrule list is updated inplace, preserving the relative order of existing subrules.
Examples:
>>> from hgp_lib.mutations import RemoveIntermediateOperator
>>> from hgp_lib.rules import And, Or, Literal
>>> rule = And([
... Literal(value=0),
... Or([
... Literal(value=1),
... Literal(value=2),
... ]),
... Literal(value=3)
... ])
>>> mutation = RemoveIntermediateOperator()
>>> mutation.apply(rule.subrules[1])
>>> rule
And(0, 3, 1, 2)
Source code in hgp_lib\mutations\operator_mutations.py
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 | |
apply(rule)
Applies an inplace structural mutation that removes the specified operator and attaches its subrules directly to the parent operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The operator rule to remove. |
required |
Raises:
| Type | Description |
|---|---|
MutationError
|
If the operator has no parent (i.e., it is the root node). |
RuntimeError
|
If the target operator is not found within its parent's subrule list, which should never occur during normal operation. |
Examples:
>>> from hgp_lib.mutations import RemoveIntermediateOperator
>>> from hgp_lib.rules import Or, And, Literal
>>> rule = Or([
... Literal(value=1),
... And([
... Literal(value=2),
... Literal(value=3),
... ]),
... Literal(value=4)
... ])
>>> mutation = RemoveIntermediateOperator()
>>> mutation.apply(rule.subrules[1])
>>> rule
Or(1, 4, 2, 3)
Source code in hgp_lib\mutations\operator_mutations.py
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 | |
hgp_lib.mutations.operator_mutations.ReplaceOperator
Bases: Mutation
The ReplaceOperator mutation replaces an operator node (e.g., And, Or) with another operator type chosen
randomly from the provided set of operator classes. The transformation occurs inplace, preserving the subrules
and other attributes of the node.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
operator_types |
Tuple[Type[Rule]]
|
Tuple of operator classes that can replace one another (e.g., |
Notes
- The mutation has no effect on literal nodes.
- The operator type is switched inplace by directly reassigning the node's
__class__attribute. - The replacement operator is always different from the current operator type.
Examples:
>>> from hgp_lib.mutations import ReplaceOperator
>>> from hgp_lib.rules import And, Or, Literal
>>> rule = And([Literal(value=0), Literal(value=1)])
>>> mutation = ReplaceOperator(operator_types=(Or, And))
>>> mutation.apply(rule)
>>> rule
Or(0, 1)
Source code in hgp_lib\mutations\operator_mutations.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
apply(rule)
Applies an inplace operator replacement mutation to the given Rule, changing its type to a different operator
from the available set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The operator rule to replace. Must be an instance of one of the |
required |
Examples:
>>> from hgp_lib.mutations import ReplaceOperator
>>> from hgp_lib.rules import And, Or, Literal
>>> rule = Or([Literal(value=2), Literal(value=3)])
>>> mutation = ReplaceOperator()
>>> mutation.apply(rule)
>>> rule
And(2, 3)
Source code in hgp_lib\mutations\operator_mutations.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | |
hgp_lib.mutations.operator_mutations.AddLiteral
Bases: Mutation
The AddLiteral mutation adds a new literal subrule to an operator node (e.g., And, Or).
The new literal is chosen randomly from the available literal space, ensuring it does not duplicate
an existing literal value already present in the operator.
Attributes:
| Name | Type | Description |
|---|---|---|
is_literal_mutation |
bool
|
|
is_operator_mutation |
bool
|
|
available_literals |
Set[int]
|
Set of all possible literal indices from which new literals are sampled. |
Notes
- The mutation raises a
MutationErrorif all possible literals are already present under the operator. - The added literal's negation flag is determined randomly with equal probability.
- The mutation operates inplace, modifying the operator's list of subrules directly.
Examples:
>>> from hgp_lib.mutations import AddLiteral
>>> from hgp_lib.rules import And, Literal
>>> rule = And([Literal(value=0), Literal(value=1)])
>>> mutation = AddLiteral(num_literals=3)
>>> mutation.apply(rule)
>>> rule.subrules[2].negated=True # Setting negated to have deterministic output
>>> rule
And(0, 1, ~2)
Source code in hgp_lib\mutations\operator_mutations.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | |
apply(rule)
Adds a new literal subrule to the given operator node. The new literal's value is selected randomly from the remaining available literals not already present in the operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rule
|
Rule
|
The operator rule to which the new literal will be added. |
required |
Raises:
| Type | Description |
|---|---|
MutationError
|
If no new literal values are available for addition. |
Examples:
>>> from hgp_lib.mutations import AddLiteral
>>> from hgp_lib.rules import Or, Literal
>>> mutation = AddLiteral(num_literals=3)
>>> rule = Or([Literal(value=0), Literal(value=1)])
>>> mutation.apply(rule)
>>> rule.subrules[2].negated=False # Setting negated to have deterministic output
>>> rule.subrules[2]
2
>>> rule
Or(0, 1, 2)
Source code in hgp_lib\mutations\operator_mutations.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | |