Skip to content

Commit a41f6cf

Browse files
committed
starting merging of functionality for copy value
1 parent 1976f81 commit a41f6cf

21 files changed

Lines changed: 135 additions & 336 deletions

core/src/main/kotlin/org/evomaster/core/problem/util/ParamUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ class ParamUtil {
274274

275275
fun generateParamId(list: Array<String>): String = list.joinToString(separator)
276276

277-
@Deprecated(message = "Rather use GeneUtils.getWrappedValueGene(gene)",
277+
@Deprecated(message = "Rather use getLeafGene()",
278278
replaceWith = ReplaceWith("GeneUtils.getWrappedValueGene(gene)"))
279279
fun getValueGene(gene: Gene): Gene {
280280
return gene.getLeafGene()!!

core/src/main/kotlin/org/evomaster/core/search/gene/Gene.kt

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,17 @@ abstract class Gene(
342342
return this
343343
}
344344

345+
/**
346+
* Return the gene used for the phenotype.
347+
* Most of the time this would be `this` gene.
348+
* Note, it is different from the concept of "wrapper", as the wrapper itself can impact
349+
* the phenotype.
350+
*
351+
* This is mainly used to handle very special cases such as [StringGene] and [SeededGene]
352+
*/
353+
open fun getPhenotype() : Gene{
354+
return this
355+
}
345356

346357

347358
protected fun matchingClass(klass: Class<*>, strict: Boolean): Boolean {
@@ -903,7 +914,7 @@ abstract class Gene(
903914
all.add(this)
904915
bindingGenes.filterNot { all.contains(it) }.forEach { b ->
905916
all.add(b)
906-
if (!b.unsafeSetFromStringValue(this))
917+
if (!b.copyValueFrom(this))
907918
LoggingUtil.uniqueWarn(
908919
log,
909920
"fail to bind the gene (${b.name} with the type ${b::class.java.simpleName}) based on this gene (${this.name} with ${this::class.java.simpleName})"
@@ -1106,44 +1117,35 @@ abstract class Gene(
11061117
* Rather use [copyValueFrom], which internally it calls this method,
11071118
* and then revert in case of constraint violations.
11081119
*
1109-
* @return whether the binding performs successfully.
1120+
* @return whether the value is copied based on [other] successfully.
1121+
* This is based only on the gene type.
1122+
* _WARNING_:
1123+
* - `true` might still leave the gene in an inconsistent state (ie violated constraints)
1124+
* - `false` might still apply partial updates (eg, think of an objects with several fields)
1125+
*
1126+
* Do not call directly outside this package. Call [copyValueFrom]
11101127
*
11111128
* TODO unfortunately, Kotlin has major design flows that do not allow package-level and true protected-level
11121129
* scope, like in Java :(
11131130
* This is a case in which is much worse than Java.
11141131
* But it could be simulated with Detekt and a rule like @PackagePrivate
11151132
*/
1116-
@Deprecated("Do not call directly outside this package. Call setFromDifferentGene")
1117-
//TODO remove deprecated once we integrate @PackagePrivate
1118-
internal abstract fun unsafeSetFromStringValue(gene: Gene): Boolean
1119-
1120-
1121-
/**
1122-
* copy value based on [other]
1123-
* in some case, the [other] might not satisfy constraints of [this gene],
1124-
* then copying will not be performed successfully
1125-
*
1126-
* FIXME unclear if side-effects or not
1127-
*
1128-
* @return whether the value is copied based on [other] successfully
1129-
*/
11301133
abstract fun unsafeCopyValueFrom(other: Gene): Boolean
11311134

11321135

11331136
/**
1134-
* Update current value of this gene, base on other gene.
1135-
* This is not [unsafeCopyValueFrom], as the gene could be different.
1136-
* FIXME that comment seems wrong
1137+
* Update current value of this gene, base on [other] gene.
11371138
* If for any reason the update fails, there is not going to be any side-effects.
1139+
* A successful update must guarantee that the gene remains valid (ie, no violated constraints).
11381140
*
11391141
* @return if the update was successful
11401142
*/
11411143
fun copyValueFrom(gene: Gene, undoIfUpdateFails: Boolean = true): Boolean {
11421144

11431145
//FIXME current implementation leads to infinite loops. must fix copyValueFrom
1144-
//return updateValueOnlyIfValid( { setValueBasedOn(gene) } , undoIfUpdateFails)
1146+
//return updateValueOnlyIfValid( { unsafeCopyValueFrom(gene) } , undoIfUpdateFails)
11451147
//TODO update once fixed
1146-
return unsafeSetFromStringValue(gene)
1148+
return unsafeCopyValueFrom(gene)
11471149
}
11481150

11491151
/*

core/src/main/kotlin/org/evomaster/core/search/gene/SeededGene.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ class SeededGene<T>(
7777
}
7878

7979
/**
80-
* @return a gene representing [this]
80+
* @return a gene representing `this`
8181
*/
82-
fun getPhenotype() : T{
82+
override fun getPhenotype() : Gene{
8383
return if (!employSeeded) gene else seeded.values[seeded.index]
8484
}
8585

core/src/main/kotlin/org/evomaster/core/search/gene/collection/ArrayGene.kt

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -252,52 +252,34 @@ class ArrayGene<T>(
252252
253253
TODO might bind based on value instead of replacing them
254254
*/
255-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
256-
if(gene is ArrayGene<*> && gene.template::class.java.simpleName == template::class.java.simpleName){
255+
256+
override fun unsafeCopyValueFrom(other: Gene): Boolean {
257+
258+
if(other is ArrayGene<*> && other.template::class.java.simpleName == template::class.java.simpleName){
259+
257260
killAllChildren()
258-
val elements = gene.elements.mapNotNull { it.copy() as? T}.toMutableList()
261+
val elements = other.elements.mapNotNull { it.copy() as? T}.toMutableList()
259262
elements.forEach { it.resetLocalIdRecursively() }
260-
if (!uniqueElements || gene.uniqueElements || !isElementApplicableToUniqueCheck(ParamUtil.getValueGene(template)))
263+
264+
if (!uniqueElements
265+
|| other.uniqueElements
266+
|| !isElementApplicableToUniqueCheck(template.getLeafGene())) {
267+
261268
addChildren(elements)
262-
else{
269+
270+
} else{
263271
val unique = elements.filterIndexed { index, t ->
264272
index == elements.indexOfLast { l-> ParamUtil.getValueGene(l).containsSameValueAs(ParamUtil.getValueGene(t)) }
265273
}
266-
Lazy.assert {
267-
unique.isNotEmpty()
268-
}
274+
Lazy.assert { unique.isNotEmpty() }
269275
addChildren(unique)
270276
}
271277
return true
272278
}
273-
LoggingUtil.uniqueWarn(
274-
log,
275-
"cannot bind ArrayGene with the template (${template::class.java.simpleName}) with ${gene::class.java.simpleName}"
276-
)
279+
LoggingUtil.uniqueWarn(log, "cannot bind ArrayGene with the template (${template::class.java.simpleName}) with ${gene::class.java.simpleName}")
277280
return false
278281
}
279282

280-
override fun unsafeCopyValueFrom(other: Gene): Boolean {
281-
if (other !is ArrayGene<*>) {
282-
throw IllegalArgumentException("Invalid gene type ${other.javaClass}")
283-
}
284-
285-
if (this.template::class.simpleName != other.template::class.simpleName) return false
286-
287-
return updateValueOnlyIfValid(
288-
{
289-
killAllChildren()
290-
// check maxSize
291-
val elements = (if(maxSize!= null && other.elements.size > maxSize!!)
292-
other.elements.subList(0, maxSize!!) else other.elements).map { e -> e.copy() as T }.toMutableList()
293-
// build parents for [element]
294-
addChildren(elements)
295-
true
296-
},
297-
false
298-
)
299-
}
300-
301283
@Deprecated("Do not call directly outside this package. Call setFromStringValue")
302284
/**
303285
* To set the Array children from a String.

core/src/main/kotlin/org/evomaster/core/search/gene/collection/EnumGene.kt

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -207,26 +207,13 @@ class EnumGene<T : Comparable<T>>(
207207
}
208208

209209
override fun unsafeCopyValueFrom(other: Gene): Boolean {
210-
if (other !is EnumGene<*>) {
211-
throw IllegalArgumentException("Invalid gene type ${other.javaClass}")
212-
}
213-
val current = this.index
214-
this.index = other.index
215-
if (!isLocallyValid()){
216-
this.index = current
217-
return false
218-
}
219-
220-
return true
221-
}
222210

223-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
224-
when {
225-
gene is EnumGene<*> -> index == gene.index
226-
gene is StringGene && gene.getSpecializationGene() != null -> return unsafeSetFromStringValue(gene.getSpecializationGene()!!)
211+
val phenotype = other.getPhenotype()
212+
when(phenotype) {
213+
is EnumGene<*> -> index == phenotype.index
227214
else -> {
228215
// since the binding is derived, it is not always true.
229-
log.info("cannot bind EnumGene with ${gene::class.java.simpleName}")
216+
log.info("cannot bind EnumGene with ${phenotype::class.java.simpleName}")
230217
return false
231218
}
232219
}

core/src/main/kotlin/org/evomaster/core/search/gene/collection/FixedMapGene.kt

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,13 @@ class FixedMapGene<K, V>(
5959
/*
6060
Note that value binding cannot be performed on the [elements]
6161
*/
62-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
62+
override fun unsafeCopyValueFrom(gene: Gene): Boolean {
63+
6364
if(gene is FixedMapGene<*, *> && gene.template::class.java.simpleName == template::class.java.simpleName){
6465
killAllChildren()
65-
val elements = gene.elements.mapNotNull { it.copy() as? PairGene<K, V> }.toMutableList()
66+
val elements = gene.elements
67+
.mapNotNull { it.copy() as? PairGene<K, V> }
68+
.toMutableList()
6669
elements.forEach { it.resetLocalIdRecursively() }
6770
addChildren(elements)
6871
return true
@@ -73,22 +76,4 @@ class FixedMapGene<K, V>(
7376
)
7477
return false
7578
}
76-
77-
override fun unsafeCopyValueFrom(other: Gene): Boolean {
78-
if (other !is FixedMapGene<*, *>) {
79-
throw IllegalArgumentException("Invalid gene type ${other.javaClass}")
80-
}
81-
82-
return updateValueOnlyIfValid({
83-
killAllChildren()
84-
// maxSize
85-
val copy = (if (maxSize!=null && other.elements.size > maxSize!!)
86-
other.elements.subList(0, maxSize!!)
87-
else other.elements)
88-
.map { e -> e.copy() as PairGene<K, V> }
89-
.toMutableList()
90-
addChildren(copy)
91-
true
92-
},false)
93-
}
9479
}

core/src/main/kotlin/org/evomaster/core/search/gene/collection/FlexibleMapGene.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package org.evomaster.core.search.gene.collection
22

3+
import org.evomaster.core.logging.LoggingUtil
34
import org.evomaster.core.search.gene.Gene
45
import org.evomaster.core.search.gene.ObjectGene
56
import org.evomaster.core.search.gene.wrapper.FlexibleGene
67
import org.evomaster.core.search.gene.wrapper.FlexibleGene.Companion.wrapWithFlexibleGene
8+
import org.slf4j.Logger
9+
import org.slf4j.LoggerFactory
710

811
/**
912
* This represents a MapGene whose values do not follow a specific gene type, ie [FlexibleGene],
@@ -27,6 +30,11 @@ where T : Gene {
2730
constructor(name : String, key: T, value: Gene, valueClasses : List<Class<*>>?, maxSize: Int? = null, minSize: Int? = null): this(name,
2831
PairGene("template", key, wrapWithFlexibleGene(value, valueClasses)), maxSize, minSize)
2932

33+
companion object {
34+
private val log: Logger = LoggerFactory.getLogger(FlexibleMapGene::class.java)
35+
}
36+
37+
3038
override fun copyContent(): Gene {
3139
return FlexibleMapGene(
3240
name,
@@ -49,13 +57,9 @@ where T : Gene {
4957
}.all { it }
5058
}
5159

52-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
53-
//TODO
54-
return false
55-
}
56-
5760
override fun unsafeCopyValueFrom(other: Gene): Boolean {
5861
//TODO
62+
LoggingUtil.uniqueWarn(log,"unsafeCopyValueFrom() not implemented for FlexibleMapGene")
5963

6064
return false
6165
}

core/src/main/kotlin/org/evomaster/core/search/gene/collection/PairGene.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,13 @@ class PairGene<F,S>(
6969
}
7070

7171

72-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
73-
if (gene !is PairGene<*, *>) {
74-
throw IllegalArgumentException("Invalid gene type ${gene.javaClass}")
75-
}
76-
return first.unsafeSetFromStringValue(gene.first) && second.unsafeSetFromStringValue(gene.second)
77-
}
7872

7973
override fun unsafeCopyValueFrom(other: Gene): Boolean {
8074
if (other !is PairGene<*, *>) {
81-
throw IllegalArgumentException("Invalid gene type ${other.javaClass}")
75+
return false
8276
}
83-
return updateValueOnlyIfValid(
84-
{
85-
first.unsafeCopyValueFrom(other.first) && second.unsafeCopyValueFrom(other.second)
86-
}, true
87-
)
77+
78+
return first.unsafeCopyValueFrom(other.first) && second.unsafeCopyValueFrom(other.second)
8879
}
8980

9081
override fun copyContent(): Gene {

core/src/main/kotlin/org/evomaster/core/search/gene/collection/TaintedArrayGene.kt

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -122,33 +122,15 @@ class TaintedArrayGene(
122122
return this.taintedValue == other.taintedValue
123123
}
124124

125-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
126-
if(gene !is TaintedArrayGene){
127-
throw IllegalArgumentException("Other is not a TaintedArray: ${gene::class.java}")
128-
}
129-
130-
if(arrayGene != null && gene.arrayGene != null){
131-
return arrayGene!!.unsafeSetFromStringValue(gene.arrayGene!!)
132-
}
133125

134-
return false
135-
}
136126

137127
override fun unsafeCopyValueFrom(other: Gene): Boolean {
138128
if(other !is TaintedArrayGene){
139-
throw IllegalArgumentException("Other is not a TaintedArray: ${other::class.java}")
129+
return false
140130
}
141131

142-
return updateValueOnlyIfValid(
143-
{
144-
val ok = this.arrayGene?.unsafeCopyValueFrom(other.arrayGene!!)?:true
145-
if (ok){
146-
this.taintedValue = other.taintedValue
147-
this.isActive = other.isActive
148-
}
149-
ok
150-
}, false
151-
)
132+
return this.arrayGene?.unsafeCopyValueFrom(other.arrayGene!!)
133+
?: true
152134
}
153135

154136
override fun getPossiblyTaintedValue(): String {

core/src/main/kotlin/org/evomaster/core/search/gene/collection/TaintedMapGene.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.evomaster.core.search.gene.collection
33
import org.evomaster.client.java.instrumentation.shared.TaintInputName
44
import org.evomaster.core.Lazy
55
import org.evomaster.core.StaticCounter
6+
import org.evomaster.core.logging.LoggingUtil
67
import org.evomaster.core.search.gene.Gene
78
import org.evomaster.core.search.gene.interfaces.TaintableGene
89
import org.evomaster.core.search.gene.wrapper.CustomMutationRateGene
@@ -226,15 +227,11 @@ class TaintedMapGene(
226227

227228
override fun unsafeCopyValueFrom(other: Gene): Boolean {
228229
//TODO
230+
LoggingUtil.uniqueWarn(log,"unsafeCopyValueFrom() not implemented for TaintedMapGene")
229231

230232
return false
231233
}
232234

233-
override fun unsafeSetFromStringValue(gene: Gene): Boolean {
234-
//TODO
235-
236-
return false
237-
}
238235

239236
override fun getPossiblyTaintedValue(): String {
240237
return taintId

0 commit comments

Comments
 (0)