use crate::types::TermLiteral;
use crate::types::{AtomicFormula, FComp, Term, TypedVariables};
#[derive(Debug, Clone, PartialEq)]
pub enum GoalDefinition {
AtomicFormula(AtomicFormula<Term>),
Literal(TermLiteral),
And(Vec<GoalDefinition>),
Or(Vec<GoalDefinition>),
Not(Box<GoalDefinition>),
Imply(Box<GoalDefinition>, Box<GoalDefinition>),
Exists(TypedVariables, Box<GoalDefinition>),
ForAll(TypedVariables, Box<GoalDefinition>),
FComp(FComp),
}
impl GoalDefinition {
#[inline(always)]
pub const fn new_atomic_formula(value: AtomicFormula<Term>) -> Self {
Self::AtomicFormula(value)
}
#[inline(always)]
pub const fn new_literal(value: TermLiteral) -> Self {
Self::Literal(value)
}
#[inline(always)]
pub fn new_and<T: IntoIterator<Item = GoalDefinition>>(values: T) -> Self {
Self::And(values.into_iter().collect())
}
#[inline(always)]
pub fn new_or<T: IntoIterator<Item = GoalDefinition>>(values: T) -> Self {
Self::Or(values.into_iter().collect())
}
#[inline(always)]
pub fn new_not(value: GoalDefinition) -> Self {
Self::Not(Box::new(value))
}
#[inline(always)]
pub fn new_imply_tuple(tuple: (GoalDefinition, GoalDefinition)) -> Self {
Self::new_imply(tuple.0, tuple.1)
}
#[inline(always)]
pub fn new_imply(a: GoalDefinition, b: GoalDefinition) -> Self {
Self::Imply(Box::new(a), Box::new(b))
}
#[inline(always)]
pub fn new_exists_tuple(tuple: (TypedVariables, GoalDefinition)) -> Self {
Self::new_exists(tuple.0, tuple.1)
}
#[inline(always)]
pub fn new_exists(variables: TypedVariables, gd: GoalDefinition) -> Self {
Self::Exists(variables, Box::new(gd))
}
#[inline(always)]
pub fn new_forall_tuple(tuple: (TypedVariables, GoalDefinition)) -> Self {
Self::new_forall(tuple.0, tuple.1)
}
#[inline(always)]
pub fn new_forall(variables: TypedVariables, gd: GoalDefinition) -> Self {
Self::ForAll(variables, Box::new(gd))
}
#[inline(always)]
pub const fn new_f_comp(f_comp: FComp) -> Self {
Self::FComp(f_comp)
}
pub fn is_empty(&self) -> bool {
match self {
GoalDefinition::AtomicFormula(_) => false,
GoalDefinition::Literal(_) => false,
GoalDefinition::And(x) => x.iter().all(|y| y.is_empty()),
GoalDefinition::Or(x) => x.iter().all(|y| y.is_empty()),
GoalDefinition::Not(x) => x.is_empty(),
GoalDefinition::Imply(x, y) => x.is_empty() && y.is_empty(),
GoalDefinition::Exists(_, x) => x.is_empty(),
GoalDefinition::ForAll(_, x) => x.is_empty(),
GoalDefinition::FComp(_) => false,
}
}
}