// Operators pub enum BinaryOperator { Addition, Subtraction, Multiplication, Division, Modulo, Exponentiation, } pub enum ComparisonOperator { Greater, Less, LessOrEqual, GreaterOrEqual, NotEqual, Equal, } pub enum UnaryOperator { AbsoluteValue, Negation, } // Primitives #[derive(Eq, Hash, PartialEq)] pub struct FunctionDeclaration { pub name: String, pub arity: usize, } #[derive(Eq, Hash, PartialEq)] pub struct PredicateDeclaration { pub name: String, pub arity: usize, } #[derive(Eq, Hash, PartialEq)] pub struct VariableDeclaration { pub name: String, } pub type VariableDeclarations = std::collections::HashSet>; pub struct VariableDeclarationStack { pub free_variable_declarations: VariableDeclarations, bound_variable_declaration_stack: Vec>, } impl VariableDeclarationStack { pub fn find(&self, variable_name: &str) -> Option> { for variable_declarations in self.bound_variable_declaration_stack.iter().rev() { if let Some(variable_declaration) = variable_declarations.iter().find(|x| x.name == variable_name) { return Some(std::rc::Rc::clone(&variable_declaration)); } } if let Some(variable_declaration) = self.free_variable_declarations.iter().find(|x| x.name == variable_name) { return Some(std::rc::Rc::clone(&variable_declaration)); } None } pub fn find_or_create(&mut self, variable_name: &str) -> std::rc::Rc { if let Some(variable_declaration) = self.find(variable_name) { return variable_declaration; } let variable_declaration = VariableDeclaration { name: variable_name.to_owned(), }; let variable_declaration = std::rc::Rc::new(variable_declaration); self.free_variable_declarations.insert(std::rc::Rc::clone(&variable_declaration)); variable_declaration } pub fn push(&mut self, bound_variable_declarations: std::rc::Rc) { self.bound_variable_declaration_stack.push(bound_variable_declarations); } pub fn pop(&mut self) { // TODO: return error instead self.bound_variable_declaration_stack.pop().expect("bound variable is empty, cannot pop last element"); } } // Terms pub struct BinaryOperation { pub operator: BinaryOperator, pub left: Box, pub right: Box, } pub struct Function { pub declaration: std::rc::Rc, pub arguments: Vec>, } pub enum SpecialInteger { Infimum, Supremum, } pub struct UnaryOperation { pub operator: UnaryOperator, pub argument: Box, } pub struct Variable { pub declaration: std::rc::Rc, } // Formulas pub struct Biconditional { pub left: Box, pub right: Box, } pub struct Comparison { pub operator: ComparisonOperator, pub left: Box, pub right: Box, } pub struct Exists { pub parameters: Vec>, pub argument: Box, } pub struct ForAll { pub parameters: Vec>, pub argument: Box, } pub struct Implies { pub antecedent: Box, pub implication: Box, } pub struct Predicate { pub declaration: std::rc::Rc, pub arguments: Vec>, } // Variants pub enum Term { BinaryOperation(BinaryOperation), Boolean(bool), Function(Function), Integer(i32), SpecialInteger(SpecialInteger), String(String), Symbolic(String), UnaryOperation(UnaryOperation), Variable(Variable), } pub type Terms = Vec>; pub enum Formula { And(Formulas), Biconditional(Biconditional), Boolean(bool), Comparison(Comparison), Exists(Exists), ForAll(ForAll), Implies(Implies), Not(Box), Or(Formulas), Predicate(Predicate), } pub type Formulas = Vec>;