mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
9a7c364c71
- This makes `-` for stdin work. - `--ignore-missing` now works with `--standard-json`, though it's not very useful because there can be at most one input file. - Separate errors for situations where there are no input files on the command line (this can be detected in the parser) and where they are not present on disk.
163 lines
6.0 KiB
C++
163 lines
6.0 KiB
C++
/*
|
|
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
|
|
/**
|
|
* Miscellaneous utilities for use in yul-phaser's test cases.
|
|
*
|
|
* - Generic code that's only used in these particular tests.
|
|
* - Convenience functions and wrappers to make tests more concise.
|
|
* - Mocks and dummy objects/functions used in multiple test suites.
|
|
*
|
|
* Note that the code included here may be not as generic, robust and/or complete as it could be
|
|
* since it's not meant for production use. If some utility seems useful enough to be moved to
|
|
* the normal code base, you should review its implementation before doing so.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <tools/yulPhaser/Chromosome.h>
|
|
#include <tools/yulPhaser/FitnessMetrics.h>
|
|
#include <tools/yulPhaser/Mutations.h>
|
|
#include <tools/yulPhaser/Population.h>
|
|
|
|
#include <boost/test/tools/detail/print_helper.hpp>
|
|
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <string>
|
|
#include <tuple>
|
|
#include <vector>
|
|
|
|
// OPERATORS FOR BOOST::TEST
|
|
|
|
/// Output operator for arbitrary two-element tuples.
|
|
/// Necessary to make BOOST_TEST() work with such tuples.
|
|
template<typename T1, typename T2>
|
|
std::ostream& operator<<(std::ostream& _output, std::tuple<T1, T2> const& _tuple)
|
|
{
|
|
_output << "(" << std::get<0>(_tuple) << ", " << std::get<1>(_tuple) << ")";
|
|
return _output;
|
|
}
|
|
|
|
namespace boost::test_tools::tt_detail
|
|
{
|
|
|
|
// Boost won't find the << operator unless we put it in the std namespace which is illegal.
|
|
// The recommended solution is to overload print_log_value<> struct and make it use our global operator.
|
|
template<typename T1,typename T2>
|
|
struct print_log_value<std::tuple<T1, T2>>
|
|
{
|
|
void operator()(std::ostream& _output, std::tuple<T1, T2> const& _tuple) { ::operator<<(_output, _tuple); }
|
|
};
|
|
|
|
}
|
|
|
|
namespace solidity::phaser::test
|
|
{
|
|
|
|
/**
|
|
* Fitness metric that only takes into account the number of optimisation steps in the chromosome.
|
|
* Recommended for use in tests because it's much faster than ProgramSize metric and it's very
|
|
* easy to guess the result at a glance.
|
|
*/
|
|
class ChromosomeLengthMetric: public FitnessMetric
|
|
{
|
|
public:
|
|
using FitnessMetric::FitnessMetric;
|
|
size_t evaluate(Chromosome const& _chromosome) override { return _chromosome.length(); }
|
|
};
|
|
|
|
// MUTATIONS
|
|
|
|
/// Mutation that always replaces the whole chromosome with the one specified in the parameter.
|
|
std::function<Mutation> wholeChromosomeReplacement(Chromosome _newChromosome);
|
|
|
|
/// Mutation that always replaces the optimisation step at position @a _geneIndex with @a _geneValue.
|
|
///
|
|
/// The chromosome must be long enough for this position to exist.
|
|
std::function<Mutation> geneSubstitution(size_t _geneIndex, std::string _geneValue);
|
|
|
|
// CHROMOSOME AND POPULATION HELPERS
|
|
|
|
/// Returns a vector containing lengths of all chromosomes in the population (in the same order).
|
|
std::vector<size_t> chromosomeLengths(Population const& _population);
|
|
|
|
/// Returns the number of genes that differ between two chromosomes.
|
|
/// If the chromnosomes have different lengths, the positions that are present in only one of them
|
|
/// are counted as mismatches.
|
|
size_t countDifferences(Chromosome const& _chromosome1, Chromosome const& _chromosome2);
|
|
|
|
/// Assigns indices from 0 to N to all optimisation steps available in the OptimiserSuite.
|
|
/// This is a convenience helper to make it easier to test their distribution with tools made for
|
|
/// integers.
|
|
std::map<std::string, size_t> enumerateOptmisationSteps();
|
|
|
|
// STRING UTILITIES
|
|
|
|
/// Returns the input string with all the whitespace characters (spaces, line endings, etc.) removed.
|
|
std::string stripWhitespace(std::string const& input);
|
|
|
|
/// Counts the number of times one strinng can be found inside another. Only non-overlapping
|
|
/// occurrences are counted.
|
|
size_t countSubstringOccurrences(std::string const& _inputString, std::string const& _substring);
|
|
|
|
// STATISTICAL UTILITIES
|
|
|
|
/// Calculates the mean value of a series of samples given in a vector.
|
|
///
|
|
/// Supports any integer and real type as a convenience but the precision of the result is limited
|
|
/// to the precision of type @a double as all the values are internally converted to it.
|
|
///
|
|
/// This is a very simple, naive implementation that's more than enough for tests where we usually
|
|
/// deal with relatively short sequences of small, positive integers. It's not numerically stable
|
|
/// in more complicated cases. Don't use in production.
|
|
template <typename T>
|
|
double mean(std::vector<T> const& _samples)
|
|
{
|
|
assert(_samples.size() > 0);
|
|
|
|
double sum = 0;
|
|
for (T const& sample: _samples)
|
|
sum += double(sample);
|
|
|
|
return sum / double(_samples.size());
|
|
}
|
|
|
|
/// Calculates the sum of squared differences between @a _expectedValue and the values of a series
|
|
/// of samples given in a vector.
|
|
///
|
|
/// Supports any integer and real type as a convenience but the precision of the result is limited
|
|
/// to the precision of type @a double as all the values are internally converted to it.
|
|
///
|
|
/// This is a very simple, naive implementation that's more than enough for tests where we usually
|
|
/// deal with relatively short sequences of small, positive integers. It's not numerically stable
|
|
/// in more complicated cases. Don't use in production.
|
|
template <typename T>
|
|
double meanSquaredError(std::vector<T> const& _samples, double _expectedValue)
|
|
{
|
|
assert(_samples.size() > 0);
|
|
|
|
double sumOfSquaredDifferences = 0;
|
|
for (T const& sample: _samples)
|
|
sumOfSquaredDifferences += (double(sample) - _expectedValue) * (double(sample) - _expectedValue);
|
|
|
|
return sumOfSquaredDifferences / double(_samples.size());
|
|
}
|
|
|
|
}
|