use super::*;

impl Evaluations<'_> {
    fn decode(&self, formula: u32) -> Result<(u64, u32), Error> {
        let (tag, body) = self.pair(formula).map_err(|_| Error::Formula)?;
        let tag = self.atom(tag).map_err(|_| Error::Formula)?;
        if tag > 15 {
            return Err(Error::UnsupportedOpcode);
        }
        Ok((tag, body))
    }
    pub(super) fn dispatch_cost(&self, formula: u32) -> Result<u64, Error> {
        let (tag, _) = self.decode(formula)?;
        Ok([1, 1, 1, 1, 1, 1, 1, 1, 64, 1, 64, 32, 32, 32, 32, 25][tag as usize])
    }
    fn child(
        &self,
        c: Candidate,
        position: usize,
        object: u32,
        formula: u32,
    ) -> Result<u32, Error> {
        let &id = c.premises.as_slice().get(position).ok_or(Error::Arity)?;
        let child = self.get(id)?.candidate;
        self.same(child.object, object)
            .map_err(|_| Error::Premise)?;
        self.same(child.formula, formula)
            .map_err(|_| Error::Premise)?;
        Ok(child.result)
    }
    pub(super) fn check_rule(&self, c: Candidate) -> Result<(), Error> {
        let (tag, body) = self.decode(c.formula)?;
        let arity = match tag {
            0 | 1 => 0,
            8 | 13 | 15 => 1,
            2 => 3,
            _ => 2,
        };
        if c.premises.as_slice().len() != arity {
            return Err(Error::Arity);
        }
        match tag {
            0 => self.axis(c.object, body, c.result),
            1 => self.same(c.result, body),
            8 | 13 | 15 => {
                let value = self.child(c, 0, c.object, body)?;
                self.unary(tag, value, c.result)
            }
            4 => {
                let (test, arms) = self.pair(body).map_err(|_| Error::Formula)?;
                let (yes, no) = self.pair(arms).map_err(|_| Error::Formula)?;
                let test = self.child(c, 0, c.object, test)?;
                let chosen = if self.atom(test)? == 0 { yes } else { no };
                let result = self.child(c, 1, c.object, chosen)?;
                self.same(c.result, result)
            }
            _ => {
                let (a, b) = self.pair(body).map_err(|_| Error::Formula)?;
                let left = self.child(c, 0, c.object, a)?;
                let right = self.child(c, 1, c.object, b)?;
                if tag == 2 {
                    let result = self.child(c, 2, left, right)?;
                    self.same(c.result, result)
                } else {
                    self.binary(tag, left, right, c.result)
                }
            }
        }
    }
}

Homonyms

soft3/crate/src/chain/tests/rules.rs
soft3/cybernode/rs/src/chain/tests/rules.rs
soft3/zheng/rs/src/execution/disclosed/stream/rules.rs

Graph