use super::super::super::cause::*;

//
// ProblemImplementation
//

/// Problem implementation.
pub trait ProblemImplementation {
    /// The length of the causation chain.
    fn depth(&self) -> usize;

    /// A cause in the causation chain.
    fn get(&self, depth: usize) -> Option<&Cause>;

    /// A cause in the causation chain.
    fn get_mut(&mut self, depth: usize) -> Option<&mut Cause>;

    /// The top of the causation chain.
    fn top(&self) -> Option<&Cause>;

    /// The top of the causation chain.
    fn top_mut(&mut self) -> Option<&mut Cause>;

    /// The root of the causation chain.
    fn root(&self) -> Option<&Cause>;

    /// The root of the causation chain.
    fn root_mut(&mut self) -> Option<&mut Cause>;

    /// Adds to the top of the causation chain.
    fn add_top(&mut self, cause: Cause);

    /// Inserts our causation chain under that of the given one.
    fn under(self, other: Self) -> Self;

    /// Appends our causation chain above that of the given one.
    fn above(self, other: Self) -> Self;
}
