anthem/include/anthem/AST.h

498 lines
12 KiB
C
Raw Normal View History

#ifndef __ANTHEM__AST_H
#define __ANTHEM__AST_H
#include <anthem/ASTForward.h>
namespace anthem
{
namespace ast
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// AST
//
////////////////////////////////////////////////////////////////////////////////////////////////////
// Terms are primitive (or arguments) if they are neither operations nor intervals
2017-06-01 00:15:48 +02:00
inline bool isPrimitive(const Term &term)
{
2017-06-01 00:15:48 +02:00
return (!term.is<BinaryOperation>() && !term.is<Interval>());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Primitives
////////////////////////////////////////////////////////////////////////////////////////////////////
struct BinaryOperation
{
enum class Operator
{
Plus,
Minus,
Multiplication,
Division,
Modulo,
Power
};
explicit BinaryOperation(Operator operator_, Term &&left, Term &&right)
: operator_{operator_},
left{std::move(left)},
right{std::move(right)}
{
}
BinaryOperation(const BinaryOperation &other) = delete;
BinaryOperation &operator=(const BinaryOperation &other) = delete;
BinaryOperation(BinaryOperation &&other) noexcept = default;
BinaryOperation &operator=(BinaryOperation &&other) noexcept = default;
Operator operator_;
Term left;
Term right;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Boolean
{
explicit Boolean(bool value)
: value{value}
{
}
Boolean(const Boolean &other) = delete;
Boolean &operator=(const Boolean &other) = delete;
Boolean(Boolean &&other) noexcept = default;
Boolean &operator=(Boolean &&other) noexcept = default;
bool value = false;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Comparison
{
enum class Operator
{
GreaterThan,
LessThan,
LessEqual,
GreaterEqual,
NotEqual,
Equal
};
explicit Comparison(Operator operator_, Term &&left, Term &&right)
: operator_{operator_},
left{std::move(left)},
right{std::move(right)}
{
}
Comparison(const Comparison &other) = delete;
Comparison &operator=(const Comparison &other) = delete;
Comparison(Comparison &&other) noexcept = default;
Comparison &operator=(Comparison &&other) noexcept = default;
Operator operator_;
Term left;
Term right;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Constant
{
explicit Constant(std::string &&name)
: name{std::move(name)}
{
}
Constant(const Constant &other) = delete;
Constant &operator=(const Constant &other) = delete;
Constant(Constant &&other) = default;
Constant &operator=(Constant &&other) = default;
std::string name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Function
{
explicit Function(std::string &&name)
: name{std::move(name)}
{
}
explicit Function(std::string &&name, std::vector<Term> &&arguments)
: name{std::move(name)},
arguments{std::move(arguments)}
{
}
Function(const Function &other) = delete;
Function &operator=(const Function &other) = delete;
Function(Function &&other) noexcept = default;
Function &operator=(Function &&other) noexcept = default;
std::string name;
std::vector<Term> arguments;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: refactor (limit element type to primitive terms)
struct In
{
explicit In(Term &&element, Term &&set)
: element{std::move(element)},
set{std::move(set)}
{
// While the set may be any term, the element must be primitive
assert(isPrimitive(element));
}
In(const In &other) = delete;
In &operator=(const In &other) = delete;
In(In &&other) noexcept = default;
In &operator=(In &&other) noexcept = default;
Term element;
Term set;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Integer
{
explicit Integer(int value)
: value{value}
{
}
Integer(const Integer &other) = delete;
Integer &operator=(const Integer &other) = delete;
Integer(Integer &&other) noexcept = default;
Integer &operator=(Integer &&other) noexcept = default;
int value;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Interval
{
explicit Interval(Term &&from, Term &&to)
: from{std::move(from)},
to{std::move(to)}
{
}
Interval(const Interval &other) = delete;
Interval &operator=(const Interval &other) = delete;
Interval(Interval &&other) noexcept = default;
Interval &operator=(Interval &&other) noexcept = default;
Term from;
Term to;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Predicate
{
explicit Predicate(std::string &&name)
: name{std::move(name)}
{
}
explicit Predicate(std::string &&name, std::vector<Term> &&arguments)
: name{std::move(name)},
arguments{std::move(arguments)}
{
}
Predicate(const Predicate &other) = delete;
Predicate &operator=(const Predicate &other) = delete;
Predicate(Predicate &&other) noexcept = default;
Predicate &operator=(Predicate &&other) noexcept = default;
2017-04-06 17:46:16 +02:00
std::size_t arity() const
{
return arguments.size();
}
std::string name;
std::vector<Term> arguments;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: make more use of this class
struct PredicateSignature
{
explicit PredicateSignature(std::string &&name, size_t arity)
: name{std::move(name)},
arity{arity}
{
}
PredicateSignature(const PredicateSignature &other) = delete;
PredicateSignature &operator=(const PredicateSignature &other) = delete;
// TODO: make noexcept again
// GCC versions before 7 dont declare moving std::string noexcept and would complain here
PredicateSignature(PredicateSignature &&other) = default;
PredicateSignature &operator=(PredicateSignature &&other) = default;
std::string name;
size_t arity;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct SpecialInteger
{
enum class Type
{
Infimum,
Supremum
};
explicit SpecialInteger(Type type)
: type{type}
{
}
SpecialInteger(const SpecialInteger &other) = delete;
SpecialInteger &operator=(const SpecialInteger &other) = delete;
SpecialInteger(SpecialInteger &&other) noexcept = default;
SpecialInteger &operator=(SpecialInteger &&other) noexcept = default;
Type type;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct String
{
explicit String(std::string &&text)
: text{std::move(text)}
{
}
String(const String &other) = delete;
String &operator=(const String &other) = delete;
String(String &&other) noexcept = default;
String &operator=(String &&other) noexcept = default;
std::string text;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Variable
{
explicit Variable(VariableDeclaration *declaration)
: declaration{declaration}
{
}
Variable(const Variable &other) = delete;
Variable &operator=(const Variable &other) = delete;
Variable(Variable &&other) = default;
Variable &operator=(Variable &&other) = default;
VariableDeclaration *declaration = nullptr;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct VariableDeclaration
{
enum class Type
{
UserDefined,
Head,
Body
};
explicit VariableDeclaration(Type type)
: type{type}
{
}
explicit VariableDeclaration(Type type, std::string &&name)
: type{type},
name{std::move(name)}
{
}
VariableDeclaration(const VariableDeclaration &other) = delete;
VariableDeclaration &operator=(const VariableDeclaration &other) = delete;
VariableDeclaration(VariableDeclaration &&other) = default;
VariableDeclaration &operator=(VariableDeclaration &&other) = default;
Type type;
std::string name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Expressions
////////////////////////////////////////////////////////////////////////////////////////////////////
struct And
{
And() = default;
explicit And(std::vector<Formula> &&arguments)
: arguments{std::move(arguments)}
{
}
And(const And &other) = delete;
And &operator=(const And &other) = delete;
And(And &&other) noexcept = default;
And &operator=(And &&other) noexcept = default;
std::vector<Formula> arguments;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Biconditional
{
explicit Biconditional(Formula &&left, Formula &&right)
: left{std::move(left)},
right{std::move(right)}
{
}
Biconditional(const Biconditional &other) = delete;
Biconditional &operator=(const Biconditional &other) = delete;
Biconditional(Biconditional &&other) noexcept = default;
Biconditional &operator=(Biconditional &&other) noexcept = default;
Formula left;
Formula right;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Exists
{
// TODO: rename “variables”
2017-06-01 00:15:48 +02:00
explicit Exists(VariableDeclarationPointers &&variables, Formula &&argument)
: variables{std::move(variables)},
argument{std::move(argument)}
{
}
Exists(const Exists &other) = delete;
Exists &operator=(const Exists &other) = delete;
Exists(Exists &&other) noexcept = default;
Exists &operator=(Exists &&other) noexcept = default;
2017-06-01 00:15:48 +02:00
VariableDeclarationPointers variables;
Formula argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct ForAll
{
2017-06-01 00:15:48 +02:00
explicit ForAll(VariableDeclarationPointers &&variables, Formula &&argument)
: variables{std::move(variables)},
argument{std::move(argument)}
{
}
ForAll(const ForAll &other) = delete;
ForAll &operator=(const ForAll &other) = delete;
ForAll(ForAll &&other) noexcept = default;
ForAll &operator=(ForAll &&other) noexcept = default;
2017-06-01 00:15:48 +02:00
VariableDeclarationPointers variables;
Formula argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Implies
{
explicit Implies(Formula &&antecedent, Formula &&consequent)
: antecedent{std::move(antecedent)},
consequent{std::move(consequent)}
{
}
Implies(const Implies &other) = delete;
Implies &operator=(const Implies &other) = delete;
Implies(Implies &&other) noexcept = default;
Implies &operator=(Implies &&other) noexcept = default;
Formula antecedent;
Formula consequent;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Not
{
explicit Not(Formula &&argument)
: argument{std::move(argument)}
{
}
Not(const Not &other) = delete;
Not &operator=(const Not &other) = delete;
Not(Not &&other) noexcept = default;
Not &operator=(Not &&other) noexcept = default;
Formula argument;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Or
{
Or() = default;
explicit Or(std::vector<Formula> &&arguments)
: arguments{std::move(arguments)}
{
}
Or(const Or &other) = delete;
Or &operator=(const Or &other) = delete;
Or(Or &&other) noexcept = default;
Or &operator=(Or &&other) noexcept = default;
std::vector<Formula> arguments;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// High-Level
////////////////////////////////////////////////////////////////////////////////////////////////////
struct ScopedFormula
{
2017-06-01 00:15:48 +02:00
explicit ScopedFormula(Formula &&formula, VariableDeclarationPointers &&freeVariables)
: formula{std::move(formula)},
freeVariables{std::move(freeVariables)}
{
}
2017-06-01 00:15:48 +02:00
Formula formula;
VariableDeclarationPointers freeVariables;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif