anthem 2.0.0-rc.1

A command-line application for assisting in the verification of answer set programs
Documentation
use std::fmt::{self, Display, Formatter};

pub mod asp;
pub mod fol;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Associativity {
    Left,
    Right,
}

pub trait Precedence: Display {
    fn precedence(&self) -> usize;

    fn associativity(&self) -> Associativity;

    fn mandatory_parentheses(&self) -> bool {
        false
    }

    fn fmt_operator(&self, f: &mut Formatter<'_>) -> fmt::Result;

    fn fmt_unary(&self, inner: impl Precedence, f: &mut Formatter<'_>) -> fmt::Result {
        if self.associativity() == Associativity::Left {
            self.fmt_operator(f)?;
        }

        if inner.mandatory_parentheses() || self.precedence() < inner.precedence() {
            write!(f, "({inner})")?;
        } else {
            write!(f, "{inner}")?;
        }

        if self.associativity() == Associativity::Right {
            self.fmt_operator(f)?;
        }

        Ok(())
    }

    fn fmt_binary(
        &self,
        lhs: impl Precedence,
        rhs: impl Precedence,
        f: &mut Formatter<'_>,
    ) -> fmt::Result {
        if lhs.mandatory_parentheses()
            || self.precedence() < lhs.precedence()
            || self.precedence() == lhs.precedence() && lhs.associativity() == Associativity::Right
        {
            write!(f, "({lhs})")?;
        } else {
            write!(f, "{lhs}")?;
        }

        self.fmt_operator(f)?;

        if rhs.mandatory_parentheses()
            || self.precedence() < rhs.precedence()
            || self.precedence() == rhs.precedence() && self.associativity() == Associativity::Left
        {
            write!(f, "({rhs})")
        } else {
            write!(f, "{rhs}")
        }
    }
}