mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			214 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			5.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
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <libsmtutil/Exceptions.h>
 | |
| 
 | |
| #include <libsolutil/Common.h>
 | |
| 
 | |
| #include <memory>
 | |
| #include <vector>
 | |
| 
 | |
| namespace solidity::smtutil
 | |
| {
 | |
| 
 | |
| enum class Kind
 | |
| {
 | |
| 	Int,
 | |
| 	Real,
 | |
| 	Bool,
 | |
| 	BitVector,
 | |
| 	Function,
 | |
| 	Array,
 | |
| 	Sort,
 | |
| 	Tuple
 | |
| };
 | |
| 
 | |
| struct Sort
 | |
| {
 | |
| 	Sort(Kind _kind):
 | |
| 		kind(_kind) {}
 | |
| 	virtual ~Sort() = default;
 | |
| 	virtual bool operator==(Sort const& _other) const { return kind == _other.kind; }
 | |
| 
 | |
| 	Kind const kind;
 | |
| };
 | |
| using SortPointer = std::shared_ptr<Sort>;
 | |
| 
 | |
| struct IntSort: public Sort
 | |
| {
 | |
| 	IntSort(bool _signed):
 | |
| 		Sort(Kind::Int),
 | |
| 		isSigned(_signed)
 | |
| 	{}
 | |
| 
 | |
| 	bool operator==(IntSort const& _other) const
 | |
| 	{
 | |
| 		return Sort::operator==(_other) && isSigned == _other.isSigned;
 | |
| 	}
 | |
| 
 | |
| 	bool isSigned;
 | |
| };
 | |
| 
 | |
| struct BitVectorSort: public Sort
 | |
| {
 | |
| 	BitVectorSort(unsigned _size):
 | |
| 		Sort(Kind::BitVector),
 | |
| 		size(_size)
 | |
| 	{}
 | |
| 
 | |
| 	bool operator==(BitVectorSort const& _other) const
 | |
| 	{
 | |
| 		return Sort::operator==(_other) && size == _other.size;
 | |
| 	}
 | |
| 
 | |
| 	unsigned size;
 | |
| };
 | |
| 
 | |
| struct FunctionSort: public Sort
 | |
| {
 | |
| 	FunctionSort(std::vector<SortPointer> _domain, SortPointer _codomain):
 | |
| 		Sort(Kind::Function), domain(std::move(_domain)), codomain(std::move(_codomain)) {}
 | |
| 	bool operator==(Sort const& _other) const override
 | |
| 	{
 | |
| 		if (!Sort::operator==(_other))
 | |
| 			return false;
 | |
| 		auto _otherFunction = dynamic_cast<FunctionSort const*>(&_other);
 | |
| 		smtAssert(_otherFunction, "");
 | |
| 		if (domain.size() != _otherFunction->domain.size())
 | |
| 			return false;
 | |
| 		if (!std::equal(
 | |
| 			domain.begin(),
 | |
| 			domain.end(),
 | |
| 			_otherFunction->domain.begin(),
 | |
| 			[&](SortPointer _a, SortPointer _b) { return *_a == *_b; }
 | |
| 		))
 | |
| 			return false;
 | |
| 		smtAssert(codomain, "");
 | |
| 		smtAssert(_otherFunction->codomain, "");
 | |
| 		return *codomain == *_otherFunction->codomain;
 | |
| 	}
 | |
| 
 | |
| 	std::vector<SortPointer> domain;
 | |
| 	SortPointer codomain;
 | |
| };
 | |
| 
 | |
| struct ArraySort: public Sort
 | |
| {
 | |
| 	/// _domain is the sort of the indices
 | |
| 	/// _range is the sort of the values
 | |
| 	ArraySort(SortPointer _domain, SortPointer _range):
 | |
| 		Sort(Kind::Array), domain(std::move(_domain)), range(std::move(_range)) {}
 | |
| 	bool operator==(Sort const& _other) const override
 | |
| 	{
 | |
| 		if (!Sort::operator==(_other))
 | |
| 			return false;
 | |
| 		auto _otherArray = dynamic_cast<ArraySort const*>(&_other);
 | |
| 		smtAssert(_otherArray, "");
 | |
| 		smtAssert(_otherArray->domain, "");
 | |
| 		smtAssert(_otherArray->range, "");
 | |
| 		smtAssert(domain, "");
 | |
| 		smtAssert(range, "");
 | |
| 		return *domain == *_otherArray->domain && *range == *_otherArray->range;
 | |
| 	}
 | |
| 
 | |
| 	SortPointer domain;
 | |
| 	SortPointer range;
 | |
| };
 | |
| 
 | |
| struct SortSort: public Sort
 | |
| {
 | |
| 	SortSort(SortPointer _inner): Sort(Kind::Sort), inner(std::move(_inner)) {}
 | |
| 	bool operator==(Sort const& _other) const override
 | |
| 	{
 | |
| 		if (!Sort::operator==(_other))
 | |
| 			return false;
 | |
| 		auto _otherSort = dynamic_cast<SortSort const*>(&_other);
 | |
| 		smtAssert(_otherSort, "");
 | |
| 		smtAssert(_otherSort->inner, "");
 | |
| 		smtAssert(inner, "");
 | |
| 		return *inner == *_otherSort->inner;
 | |
| 	}
 | |
| 
 | |
| 	SortPointer inner;
 | |
| };
 | |
| 
 | |
| struct TupleSort: public Sort
 | |
| {
 | |
| 	TupleSort(
 | |
| 		std::string _name,
 | |
| 		std::vector<std::string> _members,
 | |
| 		std::vector<SortPointer> _components
 | |
| 	):
 | |
| 		Sort(Kind::Tuple),
 | |
| 		name(std::move(_name)),
 | |
| 		members(std::move(_members)),
 | |
| 		components(std::move(_components))
 | |
| 	{
 | |
| 		for (size_t i = 0; i < members.size(); ++i)
 | |
| 			memberToIndex[members.at(i)] = i;
 | |
| 	}
 | |
| 
 | |
| 	SortPointer memberSort(std::string const& _member)
 | |
| 	{
 | |
| 		return components.at(memberToIndex.at(_member));
 | |
| 	}
 | |
| 
 | |
| 	bool operator==(Sort const& _other) const override
 | |
| 	{
 | |
| 		if (!Sort::operator==(_other))
 | |
| 			return false;
 | |
| 		auto _otherTuple = dynamic_cast<TupleSort const*>(&_other);
 | |
| 		smtAssert(_otherTuple, "");
 | |
| 		if (name != _otherTuple->name)
 | |
| 			return false;
 | |
| 		if (members != _otherTuple->members)
 | |
| 			return false;
 | |
| 		if (components.size() != _otherTuple->components.size())
 | |
| 			return false;
 | |
| 		if (!std::equal(
 | |
| 			components.begin(),
 | |
| 			components.end(),
 | |
| 			_otherTuple->components.begin(),
 | |
| 			[&](SortPointer _a, SortPointer _b) { return *_a == *_b; }
 | |
| 		))
 | |
| 			return false;
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	std::string const name;
 | |
| 	std::vector<std::string> const members;
 | |
| 	std::vector<SortPointer> const components;
 | |
| 	std::map<std::string, size_t> memberToIndex;
 | |
| };
 | |
| 
 | |
| 
 | |
| /** Frequently used sorts.*/
 | |
| struct SortProvider
 | |
| {
 | |
| 	static std::shared_ptr<Sort> const boolSort;
 | |
| 	static std::shared_ptr<IntSort> const uintSort;
 | |
| 	static std::shared_ptr<IntSort> const sintSort;
 | |
| 	static std::shared_ptr<IntSort> intSort(bool _signed = false);
 | |
| 	static std::shared_ptr<BitVectorSort> const bitVectorSort;
 | |
| 	static std::shared_ptr<Sort> const realSort;
 | |
| };
 | |
| 
 | |
| }
 |