[][src]Struct kontroli::Stack

pub struct Stack<A>(_);

A Vec that is iterated from the last to the first pushed element.

The motivation for this data structure is the translation of algorithms using (immutable) linked lists. These algorithms usually assume that the nth element of a list is the nth-last consed element, whereas the nth element of a Vec is the nth-first pushed element. This data structure uses a Vec inside, but the nth element of a Stack is the nth-last pushed element, that is, the nth element counted from the end of the underlying Vec.

This behaviour is convenient e.g. when dealing with de Bruijn indices.

Implementations

impl<'s> Stack<RState<'s>>[src]

pub fn match_rule(
    &self,
    rule: &Rule<'s>,
    sig: &Signature<'s>
) -> Option<Vec<Vec<RState<'s>>>>
[src]

impl<'s> Stack<RState<'s>>[src]

pub fn match_flatten(
    &self,
    rule: &Rule<'s>,
    sig: &Signature<'s>
) -> Option<Context<'s>>
[src]

Determine whether the stack of an abstract machine matches the rule's LHS.

Return a new machine context containing variable assignments in case of a match.

let syms: Symbols = vec!["id", "f", "a"].into_iter().collect();
let sig = Signature::new();

let rule = Rule::from(SRule::parse("[A] id A --> A.\n", &syms)?);
let term = Term::from(STerm::parse("id f a.\n", &syms)?);

let stack = State::new(RTerm::new(term)).whnf(&sig).stack;
let subst = stack.match_flatten(&rule, &sig).unwrap();
let subst = subst.iter().map(|rtt| (**rtt.force()).clone());

let expected = Term::from(STerm::parse("f.\n", &syms)?);
assert_eq!(vec![expected], subst.collect::<Vec<_>>());

impl<'s> Stack<RState<'s>>[src]

pub fn match_rule(
    &self,
    rule: &Rule<'s>,
    sig: &Signature<'s>
) -> Option<Vec<Vec<RState<'s>>>>
[src]

impl<'s> Stack<RState<'s>>[src]

pub fn match_flatten(
    &self,
    rule: &Rule<'s>,
    sig: &Signature<'s>
) -> Option<Context<'s>>
[src]

Determine whether the stack of an abstract machine matches the rule's LHS.

Return a new machine context containing variable assignments in case of a match.

let syms: Symbols = vec!["id", "f", "a"].into_iter().collect();
let sig = Signature::new();

let rule = Rule::from(SRule::parse("[A] id A --> A.\n", &syms)?);
let term = Term::from(STerm::parse("id f a.\n", &syms)?);

let stack = State::new(RTerm::new(term)).whnf(&sig).stack;
let subst = stack.match_flatten(&rule, &sig).unwrap();
let subst = subst.iter().map(|rtt| (**rtt.force()).clone());

let expected = Term::from(STerm::parse("f.\n", &syms)?);
assert_eq!(vec![expected], subst.collect::<Vec<_>>());

impl<A> Stack<A>[src]

pub fn new() -> Self[src]

Create an empty stack.

pub fn push(&mut self, x: A)[src]

Add an element to the top of the stack.

pub fn pop(&mut self) -> Option<A>[src]

Remove and return an element from the top of the stack.

pub fn pop_many(&mut self, n: usize)[src]

Remove n elements from the top of the stack.

pub fn clear(&mut self)[src]

Remove all elements from the stack.

pub fn len(&self) -> usize[src]

Return the number of elements on the stack.

pub fn is_empty(&self) -> bool[src]

Return true if the stack contains no elements.

pub fn get(&self, n: usize) -> Option<&A>[src]

Obtain the nth element counted from the top of the stack.

pub fn with_pushed<F, Y, E>(&mut self, x: A, f: F) -> Result<Y, E> where
    F: FnOnce(&mut Stack<A>) -> Result<Y, E>, 
[src]

Push an element on the stack, run a function on it, then pop the element.

This is to simulate function calls like f(Cons(x, l)), which assume that l is not changed in this call. If with_pushed is used consistently, then l at the end will contain the same elements as at the beginning.

pub fn iter(&self) -> impl Iterator<Item = &A>[src]

Iterate through the elements of the stack starting from the top.

Trait Implementations

impl<A: Clone> Clone for Stack<A>[src]

impl<A: Debug> Debug for Stack<A>[src]

impl<A> Default for Stack<A>[src]

impl<'s> Display for Stack<RTerm<'s>>[src]

impl<'s> Display for Stack<RTerm<'s>>[src]

impl<A> From<Vec<A>> for Stack<A>[src]

impl<A> FromIterator<A> for Stack<A>[src]

impl<A> IntoIterator for Stack<A>[src]

type Item = A

The type of the elements being iterated over.

type IntoIter = Rev<IntoIter<Self::Item>>

Which kind of iterator are we turning this into?

Auto Trait Implementations

impl<A> RefUnwindSafe for Stack<A> where
    A: RefUnwindSafe

impl<A> Send for Stack<A> where
    A: Send

impl<A> Sync for Stack<A> where
    A: Sync

impl<A> Unpin for Stack<A> where
    A: Unpin

impl<A> UnwindSafe for Stack<A> where
    A: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<I> IntoIterator for I where
    I: Iterator
[src]

type Item = <I as Iterator>::Item

The type of the elements being iterated over.

type IntoIter = I

Which kind of iterator are we turning this into?

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.