Merge pull request #9591 from ethereum/nameSimplifier

Yul name simplifier.
This commit is contained in:
chriseth 2020-09-10 16:46:27 +02:00 committed by GitHub
commit 0db79dbc29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 424 additions and 30 deletions

View File

@ -7,6 +7,8 @@ Compiler Features:
* SMTChecker: Support shifts.
* SMTChecker: Support structs.
* Yul Optimizer: Prune unused parameters in functions.
* Yul Optimizer: Try to simplify function names.
Bugfixes:
* Type Checker: Disallow ``virtual`` for modifiers in libraries.

View File

@ -32,7 +32,7 @@ namespace solidity::frontend
struct OptimiserSettings
{
static char constexpr DefaultYulOptimiserSteps[] =
"dhfoDgvulfnTUtnIf" // None of these can make stack problems worse
"NdhfoDgvulfnTUtnIf" // None of these can make stack problems worse
"["
"xarrscLM" // Turn into SSA and simplify
"cCTUtTOntnfDIul" // Perform structural simplification
@ -47,7 +47,7 @@ struct OptimiserSettings
"gvif" // Run full inliner
"CTUcarrLsTOtfDncarrIulc" // SSA plus simplify
"]"
"jmuljuljul VcTOcul jmul"; // Make source short and pretty
"jmuljuljul VcTOcul jmulN"; // Make source short and pretty
/// No optimisations at all - not recommended.
static OptimiserSettings none()

View File

@ -127,6 +127,8 @@ add_library(yul
optimiser/NameDispenser.h
optimiser/NameDisplacer.cpp
optimiser/NameDisplacer.h
optimiser/NameSimplifier.cpp
optimiser/NameSimplifier.h
optimiser/OptimiserStep.h
optimiser/OptimizerUtilities.cpp
optimiser/OptimizerUtilities.h

View File

@ -0,0 +1,122 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libyul/optimiser/NameSimplifier.h>
#include <libyul/optimiser/NameCollector.h>
#include <libyul/AsmData.h>
#include <libyul/Dialect.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libsolutil/CommonData.h>
#include <regex>
using namespace solidity::yul;
using namespace std;
NameSimplifier::NameSimplifier(
OptimiserStepContext& _context,
Block const& _ast
):
m_context(_context),
m_usedNames(_context.reservedIdentifiers)
{
for (YulString name: m_usedNames)
m_translations[name] = name;
set<YulString> allNames = NameCollector(_ast).names();
m_usedNames += allNames;
for (YulString name: allNames)
findSimplification(name);
}
void NameSimplifier::operator()(FunctionDefinition& _funDef)
{
translate(_funDef.name);
renameVariables(_funDef.parameters);
renameVariables(_funDef.returnVariables);
ASTModifier::operator()(_funDef);
}
void NameSimplifier::operator()(VariableDeclaration& _varDecl)
{
renameVariables(_varDecl.variables);
ASTModifier::operator()(_varDecl);
}
void NameSimplifier::renameVariables(vector<TypedName>& _variables)
{
for (TypedName& typedName: _variables)
translate(typedName.name);
}
void NameSimplifier::operator()(Identifier& _identifier)
{
translate(_identifier.name);
}
void NameSimplifier::operator()(FunctionCall& _funCall)
{
// The visitor on its own does not visit the function name.
if (!m_context.dialect.builtin(_funCall.functionName.name))
(*this)(_funCall.functionName);
ASTModifier::operator()(_funCall);
}
void NameSimplifier::findSimplification(YulString _name)
{
if (m_translations.count(_name))
return;
string name = _name.str();
static auto replacements = vector<pair<regex, string>>{
{regex("_\\$\\d+"), ""}, // removes AST IDs
{regex("(abi_..code.*)_to_.*"), "$1"}, // removes _to... for abi functions
{regex("(stringliteral_[0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]*"), "$1"}, // shorten string literal
{regex("tuple_t_"), ""},
{regex("_memory_ptr"), ""},
{regex("_calldata_ptr"), "_calldata"},
{regex("_fromStack"), ""},
{regex("_storage_storage"), "_storage"},
{regex("_memory_memory"), "_memory"},
{regex("t_contract\\$_([^_]*)_"), "$1_"},
{regex("index_access_t_array"), "index_access"},
{regex("[0-9]*_$"), ""}
};
for (auto const& [pattern, substitute]: replacements)
{
string candidate = regex_replace(name, pattern, substitute);
if (
!isRestrictedIdentifier(m_context.dialect, YulString(candidate)) &&
!m_usedNames.count(YulString(candidate))
)
name = candidate;
}
if (name != _name.str())
{
m_usedNames.insert(YulString(name));
m_translations[_name] = YulString(name);
}
}
void NameSimplifier::translate(YulString& _name)
{
auto it = m_translations.find(_name);
if (it != m_translations.end())
_name = it->second;
}

View File

@ -0,0 +1,76 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#pragma once
#include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h>
#include <libyul/YulString.h>
#include <libyul/optimiser/OptimiserStep.h>
#include <map>
#include <set>
#include <string>
namespace solidity::yul
{
struct Dialect;
/**
* Pass to "simplify" all identifier names.
*
* The purpose of this is to make generated code more readable, but also
* to remove AST identifiers that could lead to a different sorting order
* and thus influence e.g. the order of function inlining.
*
* Prerequisites: Disambiguator, FunctionHoister, FunctionGrouper
*/
class NameSimplifier: public ASTModifier
{
public:
static constexpr char const* name{"NameSimplifier"};
static void run(OptimiserStepContext& _context, Block& _ast)
{
NameSimplifier{_context, _ast}(_ast);
}
using ASTModifier::operator();
void operator()(VariableDeclaration& _varDecl) override;
void operator()(Identifier& _identifier) override;
void operator()(FunctionCall& _funCall) override;
void operator()(FunctionDefinition& _funDef) override;
private:
NameSimplifier(
OptimiserStepContext& _context,
Block const& _ast
);
/// Tries to rename a list of variables.
void renameVariables(std::vector<TypedName>& _variables);
void findSimplification(YulString _name);
void translate(YulString& _name);
OptimiserStepContext& m_context;
std::set<YulString> m_usedNames;
std::map<YulString, YulString> m_translations;
};
}

View File

@ -57,6 +57,7 @@
#include <libyul/optimiser/LoadResolver.h>
#include <libyul/optimiser/LoopInvariantCodeMotion.h>
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/NameSimplifier.h>
#include <libyul/backends/evm/ConstantOptimiser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
@ -181,6 +182,7 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()
LiteralRematerialiser,
LoadResolver,
LoopInvariantCodeMotion,
NameSimplifier,
RedundantAssignEliminator,
Rematerialiser,
SSAReverser,
@ -218,6 +220,7 @@ map<string, char> const& OptimiserSuite::stepNameToAbbreviationMap()
{LiteralRematerialiser::name, 'T'},
{LoadResolver::name, 'L'},
{LoopInvariantCodeMotion::name, 'M'},
{NameSimplifier::name, 'N'},
{RedundantAssignEliminator::name, 'r'},
{Rematerialiser::name, 'm'},
{SSAReverser::name, 'V'},

View File

@ -0,0 +1 @@
--optimize --ir-optimized --metadata-hash none

View File

@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
pragma experimental ABIEncoderV2;
// The point of this test is to check that the
// AST IDs are removed from the optimized IR
// so that they do not have a big effect on the
// optimizer if it has a bug that makes it
// depen on the actual identifiers.
struct S { uint x; }
struct T { uint[2] y; }
contract C {
S[2] values;
T t;
function sumArray(S[] memory _s) public returns (uint, string memory) {
values[0].x = _s[0].x;
t.y[0] = _s[1].x;
return (t.y[0], "longstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstringlongstring");
}
}

View File

@ -0,0 +1,131 @@
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "C_56" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_56_deployed")
codecopy(0, dataoffset("C_56_deployed"), _1)
return(0, _1)
}
}
object "C_56_deployed" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0xf8eddcc6, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), 32) { revert(_1, _1) }
let offset := calldataload(4)
if gt(offset, 0xffffffffffffffff) { revert(_1, _1) }
let value0 := abi_decode_t_array$_t_struct$_S_$dyn(add(4, offset), calldatasize())
let value := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, _1)))
let _2, _3 := storage_array_index_access$_t_struct$_S_storage(_1, _1)
sstore(_2, value)
let value_1 := mload(mload(memory_array_index_access$_t_struct$_S_$dyn(value0, 0x01)))
let _4, _5 := storage_array_index_access$_t_struct$_S_storage(0x02, _1)
update_storage_value_t_uint256_to_t_uint256(_4, _5, value_1)
let _6, _7 := storage_array_index_access$_t_struct$_S_storage(0x02, _1)
let vloc := extract_from_storage_value_dynamict_uint256(sload(_6), _7)
let vloc__24_mpos := convert_t_stringliteral_6490_to_t_string()
let memPos := allocateMemory(_1)
return(memPos, sub(abi_encode_uint256_t_string(memPos, vloc, vloc__24_mpos), memPos))
}
}
revert(0, 0)
}
function abi_decode_t_array$_t_struct$_S_$dyn(offset, end) -> array
{
if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }
let length := calldataload(offset)
if gt(length, 0xffffffffffffffff) { revert(array, array) }
let _1 := 0x20
let _2 := mul(length, _1)
array := allocateMemory(add(_2, _1))
let dst := array
mstore(array, length)
dst := add(array, _1)
let src := add(offset, _1)
if gt(add(add(offset, _2), _1), end) { revert(0, 0) }
let i := 0
let i_1 := i
for { } lt(i_1, length) { i_1 := add(i_1, 1) }
{
if slt(sub(end, src), _1) { revert(i, i) }
let value := allocateMemory(_1)
mstore(value, calldataload(src))
mstore(dst, value)
dst := add(dst, _1)
src := add(src, _1)
}
}
function abi_encode_uint256_t_string(headStart, value0, value1) -> tail
{
mstore(headStart, value0)
let _1 := 32
mstore(add(headStart, _1), 64)
let length := mload(value1)
mstore(add(headStart, 64), length)
let i := tail
for { } lt(i, length) { i := add(i, _1) }
{
mstore(add(add(headStart, i), 96), mload(add(add(value1, i), _1)))
}
if gt(i, length)
{
mstore(add(add(headStart, length), 96), tail)
}
tail := add(add(headStart, and(add(length, 31), not(31))), 96)
}
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) }
mstore(64, newFreePtr)
}
function convert_t_stringliteral_6490_to_t_string() -> converted
{
converted := allocateMemory(160)
mstore(converted, 100)
mstore(add(converted, 32), "longstringlongstringlongstringlo")
mstore(add(converted, 64), "ngstringlongstringlongstringlong")
mstore(add(converted, 96), "stringlongstringlongstringlongst")
mstore(add(converted, 128), "ring")
}
function extract_from_storage_value_dynamict_uint256(slot_value, offset) -> value
{
value := shr(mul(offset, 8), slot_value)
}
function memory_array_index_access$_t_struct$_S_$dyn(baseRef, index) -> addr
{
if iszero(lt(index, mload(baseRef))) { invalid() }
addr := add(add(baseRef, mul(index, 32)), 32)
}
function storage_array_index_access$_t_struct$_S_storage(array, index) -> slot, offset
{
if iszero(lt(index, 0x02)) { invalid() }
slot := add(array, index)
offset := offset
}
function update_storage_value_t_uint256_to_t_uint256(slot, offset, value)
{
let _1 := sload(slot)
let shiftBits := mul(offset, 8)
let mask := shl(shiftBits, not(0))
sstore(slot, or(and(_1, not(mask)), and(shl(shiftBits, value), mask)))
}
}
}
}

View File

@ -36,16 +36,16 @@ object "Arraysum_33" {
vloc_i := increment_t_uint256(vloc_i)
}
{
let _3, _4 := storage_array_index_access_t_array$_t_uint256_$dyn_storage(_1, vloc_i)
let _3, _4 := storage_array_index_access$_t_uint256_$dyn_storage(_1, vloc_i)
vloc_sum := checked_add_t_uint256(vloc_sum, extract_from_storage_value_dynamict_uint256(sload(_3), _4))
}
let memPos := allocateMemory(_1)
return(memPos, sub(abi_encode_tuple_t_uint256__to_t_uint256__fromStack(memPos, _1), memPos))
return(memPos, sub(abi_encode_uint(memPos, _1), memPos))
}
}
revert(0, 0)
}
function abi_encode_tuple_t_uint256__to_t_uint256__fromStack(headStart, value0) -> tail
function abi_encode_uint(headStart, value0) -> tail
{
tail := add(headStart, 32)
mstore(headStart, value0)
@ -71,7 +71,7 @@ object "Arraysum_33" {
if gt(value, not(1)) { revert(ret, ret) }
ret := add(value, 1)
}
function storage_array_index_access_t_array$_t_uint256_$dyn_storage(array, index) -> slot, offset
function storage_array_index_access$_t_uint256_$dyn_storage(array, index) -> slot, offset
{
if iszero(lt(index, sload(array))) { invalid() }
mstore(slot, array)

View File

@ -1081,13 +1081,13 @@
// let _2 := mload(0)
// if slt(sub(_1, _2), 64) { revert(0, 0) }
// sstore(0, and(calldataload(_2), sub(shl(160, 1), 1)))
// let x0, x1, x2, x3, x4 := abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(mload(7), mload(8))
// let x0, x1, x2, x3, x4 := abi_decode_addresst_uint256t_bytes_calldatat_enum$_Operation(mload(7), mload(8))
// sstore(x1, x0)
// sstore(x3, x2)
// sstore(1, x4)
// pop(abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41)))
// pop(abi_encode_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41)))
// }
// function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(headStart, dataEnd) -> value0, value1, value2, value3, value4
// function abi_decode_addresst_uint256t_bytes_calldatat_enum$_Operation(headStart, dataEnd) -> value0, value1, value2, value3, value4
// {
// if slt(sub(dataEnd, headStart), 128) { revert(value4, value4) }
// value0 := and(calldataload(headStart), sub(shl(160, 1), 1))
@ -1106,7 +1106,7 @@
// if iszero(lt(_3, 3)) { revert(value4, value4) }
// value4 := _3
// }
// function abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail
// function abi_encode_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail
// {
// tail := add(headStart, 352)
// mstore(headStart, value0)

View File

@ -473,7 +473,7 @@
// let i := _1
// for { } lt(i, length) { i := add(i, 1) }
// {
// abi_encode_t_array$_t_contract$_C_$55_$3_memory_to_t_array$_t_address_$3_memory_ptr(mload(srcPtr), pos)
// abi_encode_t_array$_C_memory(mload(srcPtr), pos)
// srcPtr := add(srcPtr, 0x20)
// pos := add(pos, 0x60)
// }
@ -483,15 +483,15 @@
// let offset := calldataload(add(_4, 64))
// let _5 := 0xffffffffffffffff
// if gt(offset, _5) { revert(_1, _1) }
// let value2 := abi_decode_t_array$_t_uint256_$dyn_memory_ptr(add(_4, offset), _3)
// let value2 := abi_decode_t_array$_t_uint256_$dyn(add(_4, offset), _3)
// let offset_1 := calldataload(add(_4, 0x60))
// if gt(offset_1, _5) { revert(_1, _1) }
// let value3 := abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(add(_4, offset_1), _3)
// let value3 := abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(add(_4, offset_1), _3)
// sstore(calldataload(_4), calldataload(add(_4, 0x20)))
// sstore(value2, value3)
// sstore(_1, pos)
// }
// function abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(offset, end) -> array
// function abi_decode_t_array$_t_array$_t_uint256_memory_$dyn(offset, end) -> array
// {
// let _1 := 0x1f
// if iszero(slt(add(offset, _1), end)) { revert(array, array) }
@ -509,7 +509,7 @@
// {
// if iszero(slt(add(src, _1), end)) { revert(0, 0) }
// let _4 := 0x2
// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_$2_memory(_4))
// let dst_1 := allocateMemory(array_allocation_size_t_array$_t_uint256_memory(_4))
// let dst_2 := dst_1
// let src_1 := src
// let _5 := add(src, _3)
@ -526,7 +526,7 @@
// src := _5
// }
// }
// function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset, end) -> array
// function abi_decode_t_array$_t_uint256_$dyn(offset, end) -> array
// {
// if iszero(slt(add(offset, 0x1f), end)) { revert(array, array) }
// let length := calldataload(offset)
@ -545,7 +545,7 @@
// src := add(src, _1)
// }
// }
// function abi_encode_t_array$_t_contract$_C_$55_$3_memory_to_t_array$_t_address_$3_memory_ptr(value, pos)
// function abi_encode_t_array$_C_memory(value, pos)
// {
// let srcPtr := value
// let i := 0
@ -569,7 +569,7 @@
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
// size := add(mul(length, 0x20), 0x20)
// }
// function array_allocation_size_t_array$_t_uint256_$2_memory(length) -> size
// function array_allocation_size_t_array$_t_uint256_memory(length) -> size
// {
// if gt(length, 0xffffffffffffffff) { revert(size, size) }
// size := mul(length, 0x20)

View File

@ -0,0 +1,34 @@
{
// This function name can be shortened, the other cannot.
function nonmstore_(x) {
nonmstore_(x)
sstore(10, calldataload(2))
}
function mstore_(x) -> y {
let t3_3_ := mstore_(x)
y := 8
sstore(y, calldataload(y))
}
let t2_ := mstore_(7)
nonmstore_(70)
}
// ----
// step: fullSuite
//
// {
// {
// pop(mstore_(7))
// nonmstore(70)
// }
// function nonmstore(x)
// {
// nonmstore(x)
// sstore(10, calldataload(2))
// }
// function mstore_(x) -> y
// {
// pop(mstore_(x))
// y := 8
// sstore(y, calldataload(y))
// }
// }

View File

@ -36,16 +36,16 @@
//
// {
// {
// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1))
// let a_1, b_1 := abi_decode_t_bytes_calldata_ptr(a, b)
// let a_2, b_2 := abi_decode_t_bytes_calldata_ptr(a_1, b_1)
// let a_3, b_3 := abi_decode_t_bytes_calldata_ptr(a_2, b_2)
// let a_4, b_4 := abi_decode_t_bytes_calldata_ptr(a_3, b_3)
// let a_5, b_5 := abi_decode_t_bytes_calldata_ptr(a_4, b_4)
// let a_6, b_6 := abi_decode_t_bytes_calldata_ptr(a_5, b_5)
// let a, b := abi_decode_t_bytes_calldata(mload(0), mload(1))
// let a_1, b_1 := abi_decode_t_bytes_calldata(a, b)
// let a_2, b_2 := abi_decode_t_bytes_calldata(a_1, b_1)
// let a_3, b_3 := abi_decode_t_bytes_calldata(a_2, b_2)
// let a_4, b_4 := abi_decode_t_bytes_calldata(a_3, b_3)
// let a_5, b_5 := abi_decode_t_bytes_calldata(a_4, b_4)
// let a_6, b_6 := abi_decode_t_bytes_calldata(a_5, b_5)
// mstore(a_6, b_6)
// }
// function abi_decode_t_bytes_calldata_ptr(offset, end) -> arrayPos, length
// function abi_decode_t_bytes_calldata(offset, end) -> arrayPos, length
// {
// if iszero(slt(add(offset, 0x1f), end)) { revert(arrayPos, arrayPos) }
// length := calldataload(offset)

View File

@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin
BOOST_TEST(chromosome.length() == allSteps.size());
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMrmVatpud");
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMNrmVatpud");
}
BOOST_AUTO_TEST_CASE(randomOptimisationStep_should_return_each_step_with_same_probability)

View File

@ -103,10 +103,10 @@ BOOST_AUTO_TEST_CASE(geneAddition_should_iterate_over_gene_positions_and_insert_
SimulationRNG::reset(1);
// f c C U n D v e j s
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f c C UC n D v e jx s"))); // 20% more
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("s f cu C U nj D v eI j sf"))); // 50% more
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("s f cu C U nj D v eO j sf"))); // 50% more
SimulationRNG::reset(2);
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f cu C U n D v e j s"))); // 10% more
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("M f ce Cv U n D v e jo s"))); // 40% more
BOOST_TEST(mutation01(chromosome) == Chromosome(stripWhitespace(" f cp C U n D v e j s"))); // 10% more
BOOST_TEST(mutation05(chromosome) == Chromosome(stripWhitespace("M f ce Ce U n D v e jo s"))); // 40% more
}
BOOST_AUTO_TEST_CASE(geneAddition_should_be_able_to_insert_before_first_position)