use super::*;

#[test]
fn all_native_rules_match_finite_dag_across_a_fresh_noun_table_per_event() {
    for tag in 0..16 {
        for value in [0, 1, 7, u32::MAX as u64] {
            let mut ar = Arena::try_new_boxed().unwrap();
            let a = atom(&mut ar, value);
            let b = atom(&mut ar, 3);
            let object = ar.pair(a, b).unwrap();
            let qa = op(&mut ar, 1, a);
            let qb = op(&mut ar, 1, b);
            let formula = match tag {
                0 => {
                    let address = atom(&mut ar, value % 4);
                    op(&mut ar, 0, address)
                }
                1 => op(&mut ar, 1, object),
                2 => {
                    let address = atom(&mut ar, 1);
                    let identity = op(&mut ar, 0, address);
                    let qf = op(&mut ar, 1, identity);
                    binary(&mut ar, 2, qa, qf)
                }
                4 => branch(&mut ar, qa, qb, qa),
                8 => op(&mut ar, 8, qb),
                13 | 15 => op(&mut ar, tag, qa),
                _ => binary(&mut ar, tag, qa, qb),
            };
            let mut records = Vec::new();
            derive(&mut ar, object, formula, &mut records);
            let wrong = atom(&mut ar, 0x1234_5678);
            let c = records.last().unwrap().candidate;
            assert_ne!(particle(&ar, wrong), particle(&ar, c.result));
            let mut rejected = SemanticStream::new(key(&ar, object, formula), limits()).unwrap();
            enter(&mut rejected, &ar, object, formula, &mut 0).unwrap();
            for &child in c.premises.as_slice() {
                emit(&mut rejected, &ar, &records, child, &mut 0);
            }
            assert_eq!(
                finish(&mut rejected, &ar, wrong, None, &mut 0),
                Err(Error::Output)
            );
            assert!(rejected.is_poisoned());
            let root = *records.last().unwrap();
            let terminal = terminal(&ar, &records);
            let finite = finite(&ar, &records);
            let summary = terminal.summary();
            assert_eq!(summary.key(), key(&ar, object, formula));
            assert_eq!(
                summary.result().particle(),
                particle(&ar, root.candidate.result)
            );
            assert_eq!(summary.cost(), root.cost);
            assert_eq!(summary.peak_frames(), root.peak);
            assert_eq!(
                (
                    summary.cost(),
                    summary.occurrences(),
                    summary.peak_frames(),
                    summary.steps()
                ),
                (
                    finite.cost(),
                    finite.occurrences(),
                    finite.peak_frames(),
                    finite.steps()
                )
            );
            assert_eq!(terminal.events(), 2 * records.len() as u64);
            assert_eq!(terminal.remaining(), 0);
        }
    }
}

#[test]
fn cached_child_metrics_and_atom_facts_survive_noun_reset_and_slot_replacement() {
    let mut ar = Arena::try_new_boxed().unwrap();
    let object = atom(&mut ar, 0);
    let q = quote(&mut ar, 7);
    let formula = binary(&mut ar, 5, q, q);
    let mut records = Vec::new();
    derive(&mut ar, object, formula, &mut records);
    let mut stream = SemanticStream::new(key(&ar, object, formula), limits()).unwrap();
    let mut nonce = 0;
    enter(&mut stream, &ar, object, formula, &mut nonce).unwrap();
    enter(&mut stream, &ar, object, q, &mut nonce).unwrap();
    let handle = finish(
        &mut stream,
        &ar,
        records[0].candidate.result,
        Some(0),
        &mut nonce,
    )
    .unwrap()
    .unwrap();
    let (stored, summary) = stream.cache(0).unwrap();
    assert_eq!(stored, handle);
    assert_eq!(handle.generation, 1);
    assert_eq!(summary.result().value(), ResultValue::Atom(7));
    assert_eq!(
        (
            summary.cost(),
            summary.occurrences(),
            summary.peak_frames(),
            summary.steps()
        ),
        (1, 1, 1, 2)
    );
    stream.reuse(handle).unwrap();
    let root = *records.last().unwrap();
    let replacement = finish(&mut stream, &ar, root.candidate.result, Some(0), &mut nonce)
        .unwrap()
        .unwrap();
    assert_eq!(replacement.generation, 2);
    let terminal = stream.bind_terminal(claim(&ar, root)).unwrap();
    assert_eq!(
        (
            terminal.summary().cost(),
            terminal.summary().occurrences(),
            terminal.summary().steps(),
            terminal.events()
        ),
        (3, 3, 6, 5)
    );
}

#[test]
fn parent_keeps_left_header_when_right_child_evicts_its_summary() {
    let mut ar = Arena::try_new_boxed().unwrap();
    let object = atom(&mut ar, 0);
    let qa = quote(&mut ar, 7);
    let qb = quote(&mut ar, 9);
    let formula = binary(&mut ar, 3, qa, qb);
    let mut records = Vec::new();
    derive(&mut ar, object, formula, &mut records);
    let mut stream = SemanticStream::new(key(&ar, object, formula), limits()).unwrap();
    let mut nonce = 0;
    enter(&mut stream, &ar, object, formula, &mut nonce).unwrap();
    for record in &records[..2] {
        enter(
            &mut stream,
            &ar,
            object,
            record.candidate.formula,
            &mut nonce,
        )
        .unwrap();
        finish(
            &mut stream,
            &ar,
            record.candidate.result,
            Some(0),
            &mut nonce,
        )
        .unwrap();
    }
    let last = *records.last().unwrap();
    finish(&mut stream, &ar, last.candidate.result, None, &mut nonce).unwrap();
    let done = stream.bind_terminal(claim(&ar, last)).unwrap();
    assert_eq!(
        done.summary().result().value(),
        ResultValue::Pair {
            left: particle(&ar, records[0].candidate.result),
            right: particle(&ar, records[1].candidate.result)
        }
    );
}

#[test]
fn canonical_field_word_and_hash_boundaries_match_native() {
    for tag in [5, 6, 7, 8, 9, 10, 14, 15] {
        for (a, b) in [
            (1, nebu::field::P - 1),
            (nebu::field::P - 1, 1),
            (0, 0),
            (u32::MAX as u64, u32::MAX as u64),
            (1, 32),
        ] {
            if (tag == 8 && a == 0) || (tag == 14 && (a > u32::MAX as u64 || b > u32::MAX as u64)) {
                continue;
            }
            let mut ar = Arena::try_new_boxed().unwrap();
            let object = atom(&mut ar, 0);
            let qa = quote(&mut ar, a);
            let qb = quote(&mut ar, b);
            let formula = if [8, 15].contains(&tag) {
                op(&mut ar, tag, qa)
            } else {
                binary(&mut ar, tag, qa, qb)
            };
            let mut records = Vec::new();
            derive(&mut ar, object, formula, &mut records);
            let done = terminal(&ar, &records);
            let finite = finite(&ar, &records);
            assert_eq!(done.summary().cost(), finite.cost());
        }
    }
}

#[test]
fn saturated_unselected_dynamic_and_service_data_preserve_selected_derivation() {
    let mut ar = Arena::try_new_boxed().unwrap();
    let object = atom(&mut ar, 0);
    let q0 = quote(&mut ar, 0);
    let q7 = quote(&mut ar, 7);
    let mut huge = q7;
    for _ in 0..64 {
        huge = binary(&mut ar, 3, huge, huge);
    }
    let dynamic = binary(&mut ar, 2, q0, q0);
    let service = op(&mut ar, 16, q0);
    for no in [huge, dynamic, service, object] {
        let cheap = branch(&mut ar, q0, q7, no);
        let formula = binary(&mut ar, 5, cheap, cheap);
        let mut records = Vec::new();
        derive(&mut ar, object, formula, &mut records);
        let done = terminal(&ar, &records);
        assert_eq!(
            (
                done.summary().cost(),
                done.summary().occurrences(),
                done.summary().peak_frames()
            ),
            (7, 7, 3)
        );
    }
}

Homonyms

neural/trident/tests/differential.rs
soft3/hemera/rs/tests/differential.rs
cyb/wysm/fuzz/fuzz_targets/differential.rs
neural/trident/src/verify/equiv/differential.rs
soft3/zheng/rs/src/execution/disclosed/evaluation/tests/differential.rs

Graph