602 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			602 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef __ANTHEM__AST_H
 | 
						|
#define __ANTHEM__AST_H
 | 
						|
 | 
						|
#include <anthem/ASTForward.h>
 | 
						|
 | 
						|
namespace anthem
 | 
						|
{
 | 
						|
namespace ast
 | 
						|
{
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// AST
 | 
						|
//
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Primitives
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct BinaryOperation
 | 
						|
{
 | 
						|
	enum class Operator
 | 
						|
	{
 | 
						|
		Plus,
 | 
						|
		Minus,
 | 
						|
		Multiplication,
 | 
						|
		Division,
 | 
						|
		Modulo
 | 
						|
	};
 | 
						|
 | 
						|
	BinaryOperation(Operator operator_, Term &&left, Term &&right)
 | 
						|
	:	operator_{operator_},
 | 
						|
		left{std::move(left)},
 | 
						|
		right{std::move(right)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Operator operator_;
 | 
						|
	Term left;
 | 
						|
	Term right;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Boolean
 | 
						|
{
 | 
						|
	Boolean(bool value)
 | 
						|
	:	value{value}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	bool value = false;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Comparison
 | 
						|
{
 | 
						|
	enum class Operator
 | 
						|
	{
 | 
						|
		GreaterThan,
 | 
						|
		LessThan,
 | 
						|
		LessEqual,
 | 
						|
		GreaterEqual,
 | 
						|
		NotEqual,
 | 
						|
		Equal
 | 
						|
	};
 | 
						|
 | 
						|
	Comparison(Operator operator_, Term &&left, Term &&right)
 | 
						|
	:	operator_{operator_},
 | 
						|
		left{std::move(left)},
 | 
						|
		right{std::move(right)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Operator operator_;
 | 
						|
	Term left;
 | 
						|
	Term right;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Constant
 | 
						|
{
 | 
						|
	Constant(std::string &&name)
 | 
						|
	:	name{std::move(name)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::string name;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Function
 | 
						|
{
 | 
						|
	Function(std::string &&name)
 | 
						|
	:	name{std::move(name)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Function(std::string &&name, std::vector<Term> &&arguments)
 | 
						|
	:	name{std::move(name)},
 | 
						|
		arguments{std::move(arguments)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::string name;
 | 
						|
	std::vector<Term> arguments;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct In
 | 
						|
{
 | 
						|
	In(Term &&element, Term &&set)
 | 
						|
	:	element{std::move(element)},
 | 
						|
		set{std::move(set)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Term element;
 | 
						|
	Term set;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Integer
 | 
						|
{
 | 
						|
	Integer(int value)
 | 
						|
	:	value{value}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	int value;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Interval
 | 
						|
{
 | 
						|
	Interval(Term &&from, Term &&to)
 | 
						|
	:	from{std::move(from)},
 | 
						|
		to{std::move(to)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Term from;
 | 
						|
	Term to;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Predicate
 | 
						|
{
 | 
						|
	Predicate(std::string &&name)
 | 
						|
	:	name{std::move(name)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Predicate(std::string &&name, std::vector<Term> &&arguments)
 | 
						|
	:	name{std::move(name)},
 | 
						|
		arguments{std::move(arguments)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::string name;
 | 
						|
	std::vector<Term> arguments;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct SpecialInteger
 | 
						|
{
 | 
						|
	enum class Type
 | 
						|
	{
 | 
						|
		Infimum,
 | 
						|
		Supremum
 | 
						|
	};
 | 
						|
 | 
						|
	SpecialInteger(Type type)
 | 
						|
	:	type{type}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Type type;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct String
 | 
						|
{
 | 
						|
	String(std::string &&text)
 | 
						|
	:	text{std::move(text)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::string text;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Variable
 | 
						|
{
 | 
						|
	enum class Type
 | 
						|
	{
 | 
						|
		UserDefined,
 | 
						|
		Reserved
 | 
						|
	};
 | 
						|
 | 
						|
	Variable(std::string &&name, Type type)
 | 
						|
	:	name{std::move(name)},
 | 
						|
		type{type}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::string name;
 | 
						|
	Type type;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Expressions
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct And
 | 
						|
{
 | 
						|
	And() = default;
 | 
						|
 | 
						|
	And(std::vector<Formula> &&arguments)
 | 
						|
	:	arguments{std::move(arguments)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::vector<Formula> arguments;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Biconditional
 | 
						|
{
 | 
						|
	Biconditional(Formula &&left, Formula &&right)
 | 
						|
	:	left{std::move(left)},
 | 
						|
		right{std::move(right)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Formula left;
 | 
						|
	Formula right;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Exists
 | 
						|
{
 | 
						|
	Exists(std::vector<Variable> &&variables, Formula &&argument)
 | 
						|
	:	variables{std::move(variables)},
 | 
						|
		argument{std::move(argument)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::vector<Variable> variables;
 | 
						|
	Formula argument;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct ForAll
 | 
						|
{
 | 
						|
	ForAll(std::vector<Variable> &&variables, Formula &&argument)
 | 
						|
	:	variables{std::move(variables)},
 | 
						|
		argument{std::move(argument)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::vector<Variable> variables;
 | 
						|
	Formula argument;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Implies
 | 
						|
{
 | 
						|
	Implies(Formula &&antecedent, Formula &&consequent)
 | 
						|
	:	antecedent{std::move(antecedent)},
 | 
						|
		consequent{std::move(consequent)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Formula antecedent;
 | 
						|
	Formula consequent;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Not
 | 
						|
{
 | 
						|
	Not(Formula &&argument)
 | 
						|
	:	argument{std::move(argument)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	Formula argument;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
struct Or
 | 
						|
{
 | 
						|
	Or() = default;
 | 
						|
 | 
						|
	Or(std::vector<Formula> &&arguments)
 | 
						|
	:	arguments{std::move(arguments)}
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	std::vector<Formula> arguments;
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Deep Copying
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
BinaryOperation deepCopy(const BinaryOperation &other);
 | 
						|
Boolean deepCopy(const Boolean &other);
 | 
						|
Comparison deepCopy(const Comparison &other);
 | 
						|
Constant deepCopy(const Constant &other);
 | 
						|
Function deepCopy(const Function &other);
 | 
						|
Integer deepCopy(const Integer &other);
 | 
						|
Interval deepCopy(const Interval &other);
 | 
						|
Predicate deepCopy(const Predicate &other);
 | 
						|
SpecialInteger deepCopy(const SpecialInteger &other);
 | 
						|
String deepCopy(const String &other);
 | 
						|
Variable deepCopy(const Variable &other);
 | 
						|
std::vector<Variable> deepCopy(const std::vector<Variable> &other);
 | 
						|
And deepCopy(const And &other);
 | 
						|
Biconditional deepCopy(const Biconditional &other);
 | 
						|
Exists deepCopy(const Exists &other);
 | 
						|
ForAll deepCopy(const ForAll &other);
 | 
						|
Implies deepCopy(const Implies &other);
 | 
						|
Not deepCopy(const Not &other);
 | 
						|
Or deepCopy(const Or &other);
 | 
						|
 | 
						|
Formula deepCopy(const Formula &formula);
 | 
						|
std::vector<Formula> deepCopy(const std::vector<Formula> &formulas);
 | 
						|
Term deepCopy(const Term &term);
 | 
						|
std::vector<Term> deepCopy(const std::vector<Term> &terms);
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
/*
 | 
						|
const auto deepCopyUniquePtr =
 | 
						|
	[](const auto &uniquePtr) -> typename std::decay<decltype(uniquePtr)>::type
 | 
						|
	{
 | 
						|
		using Type = typename std::decay<decltype(uniquePtr)>::type::element_type;
 | 
						|
		return std::make_unique<Type>(deepCopy(*uniquePtr));
 | 
						|
	};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const auto deepCopyUniquePtrVector =
 | 
						|
	[](const auto &uniquePtrVector) -> typename std::decay<decltype(uniquePtrVector)>::type
 | 
						|
	{
 | 
						|
		using Type = typename std::decay<decltype(uniquePtrVector)>::type::value_type;
 | 
						|
 | 
						|
		std::vector<Type> result;
 | 
						|
		result.reserve(uniquePtrVector.size());
 | 
						|
 | 
						|
		for (const auto &uniquePtr : uniquePtrVector)
 | 
						|
			result.emplace_back(deepCopyUniquePtr(uniquePtr));
 | 
						|
 | 
						|
		return result;
 | 
						|
	};
 | 
						|
*/
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
template<class Variant>
 | 
						|
struct VariantDeepCopyVisitor
 | 
						|
{
 | 
						|
	template<class T>
 | 
						|
	Variant visit(const T &x)
 | 
						|
	{
 | 
						|
		return deepCopy(x);
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const auto deepCopyVariant =
 | 
						|
	[](const auto &variant) -> typename std::decay<decltype(variant)>::type
 | 
						|
	{
 | 
						|
		using VariantType = typename std::decay<decltype(variant)>::type;
 | 
						|
 | 
						|
		return variant.accept(VariantDeepCopyVisitor<VariantType>());
 | 
						|
	};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const auto deepCopyVariantVector =
 | 
						|
	[](const auto &variantVector) -> typename std::decay<decltype(variantVector)>::type
 | 
						|
	{
 | 
						|
		using Type = typename std::decay<decltype(variantVector)>::type::value_type;
 | 
						|
 | 
						|
		std::vector<Type> result;
 | 
						|
		result.reserve(variantVector.size());
 | 
						|
 | 
						|
		for (const auto &variant : variantVector)
 | 
						|
			result.emplace_back(deepCopyVariant(variant));
 | 
						|
 | 
						|
		return result;
 | 
						|
	};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const auto deepCopyVector =
 | 
						|
	[](const auto &vector) -> typename std::decay<decltype(vector)>::type
 | 
						|
	{
 | 
						|
		using Type = typename std::decay<decltype(vector)>::type::value_type;
 | 
						|
 | 
						|
		std::vector<Type> result;
 | 
						|
		result.reserve(vector.size());
 | 
						|
 | 
						|
		for (const auto &element : vector)
 | 
						|
			result.emplace_back(deepCopy(element));
 | 
						|
 | 
						|
		return result;
 | 
						|
	};
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline BinaryOperation deepCopy(const BinaryOperation &other)
 | 
						|
{
 | 
						|
	return BinaryOperation(other.operator_, deepCopy(other.left), deepCopy(other.right));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Boolean deepCopy(const Boolean &other)
 | 
						|
{
 | 
						|
	return Boolean(other.value);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Comparison deepCopy(const Comparison &other)
 | 
						|
{
 | 
						|
	return Comparison(other.operator_, deepCopy(other.left), deepCopy(other.right));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Constant deepCopy(const Constant &other)
 | 
						|
{
 | 
						|
	return Constant(std::string(other.name));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Function deepCopy(const Function &other)
 | 
						|
{
 | 
						|
	return Function(std::string(other.name), deepCopy(other.arguments));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Integer deepCopy(const Integer &other)
 | 
						|
{
 | 
						|
	return Integer(other.value);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Interval deepCopy(const Interval &other)
 | 
						|
{
 | 
						|
	return Interval(deepCopy(other.from), deepCopy(other.to));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Predicate deepCopy(const Predicate &other)
 | 
						|
{
 | 
						|
	return Predicate(std::string(other.name), deepCopy(other.arguments));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline SpecialInteger deepCopy(const SpecialInteger &other)
 | 
						|
{
 | 
						|
	return SpecialInteger(other.type);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline String deepCopy(const String &other)
 | 
						|
{
 | 
						|
	return String(std::string(other.text));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Variable deepCopy(const Variable &other)
 | 
						|
{
 | 
						|
	return Variable(std::string(other.name), other.type);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline std::vector<Variable> deepCopy(const std::vector<Variable> &other)
 | 
						|
{
 | 
						|
	return deepCopyVector(other);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline And deepCopy(const And &other)
 | 
						|
{
 | 
						|
	return And(deepCopy(other.arguments));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Biconditional deepCopy(const Biconditional &other)
 | 
						|
{
 | 
						|
	return Biconditional(deepCopy(other.left), deepCopy(other.right));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Exists deepCopy(const Exists &other)
 | 
						|
{
 | 
						|
	return Exists(deepCopy(other.variables), deepCopy(other.argument));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline ForAll deepCopy(const ForAll &other)
 | 
						|
{
 | 
						|
	return ForAll(deepCopy(other.variables), deepCopy(other.argument));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline In deepCopy(const In &other)
 | 
						|
{
 | 
						|
	return In(deepCopy(other.element), deepCopy(other.set));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Implies deepCopy(const Implies &other)
 | 
						|
{
 | 
						|
	return Implies(deepCopy(other.antecedent), deepCopy(other.consequent));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Not deepCopy(const Not &other)
 | 
						|
{
 | 
						|
	return Not(deepCopy(other.argument));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Or deepCopy(const Or &other)
 | 
						|
{
 | 
						|
	return Or(deepCopy(other.arguments));
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Formula deepCopy(const Formula &formula)
 | 
						|
{
 | 
						|
	return deepCopyVariant(formula);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline std::vector<Formula> deepCopy(const std::vector<Formula> &formulas)
 | 
						|
{
 | 
						|
	return deepCopyVariantVector(formulas);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline Term deepCopy(const Term &term)
 | 
						|
{
 | 
						|
	return deepCopyVariant(term);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
inline std::vector<Term> deepCopy(const std::vector<Term> &terms)
 | 
						|
{
 | 
						|
	return deepCopyVariantVector(terms);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
}
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |