trivial-kernel 0.9.0

A Metamath Zero kernel for Trivial
Documentation
pub mod heap;
pub mod stack;
pub mod store;

use crate::error::Kind;
use crate::table::Sort;
use crate::KResult;
use crate::Table;
use crate::Var;
pub use heap::Heap;
pub use stack::Stack;
pub use store::{PackedPtr, Ptr, Store};

#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Context<S: Store> {
    pub(crate) proof_stack: Stack,
    pub(crate) proof_heap: Heap,
    pub(crate) unify_stack: Stack,
    pub(crate) unify_heap: Heap,
    pub(crate) hyp_stack: Stack,
    pub(crate) store: S,
    pub(crate) next_bv: u64,
}

impl<S: Store> Context<S> {
    pub fn proof_stack(&self) -> &Stack {
        &self.proof_stack
    }

    pub fn proof_heap(&self) -> &Heap {
        &self.proof_heap
    }

    pub fn unify_stack(&self) -> &Stack {
        &self.unify_stack
    }

    pub fn unify_heap(&self) -> &Heap {
        &self.unify_heap
    }

    pub fn store(&self) -> &S {
        &self.store
    }

    pub fn hyp_stack(&self) -> &Stack {
        &self.hyp_stack
    }

    pub fn clear_except_store(&mut self) {
        self.proof_stack.clear();
        self.proof_heap.clear();
        self.unify_stack.clear();
        self.unify_heap.clear();
        self.hyp_stack.clear();
    }

    pub fn binder_check<T: Table>(
        table: &T,
        ty: &T::Var,
        current_sort: u8,
        bv: &mut u64,
    ) -> KResult {
        let idx = ty.sort_idx();

        if idx >= current_sort {
            return Err(Kind::SortOutOfRange);
        }

        let sort = table.sort(ty.sort_idx()).ok_or(Kind::InvalidSort)?;
        let deps = ty.dependencies();

        if ty.is_bound() {
            if sort.is_strict() {
                return Err(Kind::SortIsStrict);
            }

            if deps != *bv {
                return Err(Kind::BindDep);
            }

            *bv *= 2;
        } else if (deps & !(*bv - 1)) != 0 {
            return Err(Kind::BindDep);
        }

        Ok(())
    }

    pub fn allocate_binders<T: Table<Var = S::Var>>(
        &mut self,
        table: &T,
        current_sort: u8,
        binders: &[T::Var],
    ) -> KResult {
        let mut next_bv = 1;

        for (i, ty) in binders.iter().enumerate() {
            Self::binder_check(table, ty, current_sort, &mut next_bv)?;

            let ptr = self.store.alloc_var(*ty, i as u16);
            self.proof_heap.push(ptr);
        }

        self.next_bv = next_bv;

        Ok(())
    }
}

use core::fmt::{self, Display, Formatter};

impl<S: Store> Display for Context<S> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let display = self.proof_stack.to_display(&self.store);
        writeln!(f, " Stack:\n{}", display)?;
        let display = self.unify_stack.to_display(&self.store);
        writeln!(f, " UStack:\n{}", display)?;
        let display = self.hyp_stack.to_display(&self.store);
        writeln!(f, " HStack:\n{}", display)
    }
}