use super::*;

#[test]
fn all_pure_patterns_match_native_values_costs_and_frame_boundaries() {
    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 => op(&mut ar, 0, b),
                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();
            let root = derive(&mut ar, object, formula, &mut records);
            let expected = records[root as usize];
            let mut wrong = atom(&mut ar, 0x12345678);
            if particle(&ar, wrong) == particle(&ar, expected.candidate.result) {
                wrong = atom(&mut ar, 0x12345679);
            }
            let memory = import(&ar);
            let checked = verified(&memory, &records);
            let mut forged = verified(&memory, &records[..root as usize]);
            assert_eq!(
                forged.append(Candidate {
                    result: wrong,
                    ..expected.candidate
                }),
                Err(Error::Result)
            );
            assert_eq!(
                checked.bind_last(claim(&ar, expected)).unwrap().remaining(),
                0
            );
            for budget in [expected.cost, expected.cost + 1, u64::MAX] {
                let actual = nox::sequential::reduce_cached(
                    &mut ar,
                    object,
                    formula,
                    budget,
                    nox::sequential::Limits {
                        max_frames: expected.peak,
                    },
                )
                .unwrap();
                let Outcome::Ok(result, remaining) = actual.outcome else {
                    panic!("{:?}", actual.outcome)
                };
                assert_eq!(
                    particle(&ar, result),
                    particle(&ar, expected.candidate.result)
                );
                assert_eq!(remaining, budget - expected.cost);
                assert_eq!(actual.peak_frames, expected.peak);
            }
            let below = nox::sequential::reduce_cached(
                &mut ar,
                object,
                formula,
                expected.cost - 1,
                nox::sequential::Limits {
                    max_frames: expected.peak,
                },
            )
            .unwrap();
            assert!(!matches!(below.outcome, Outcome::Ok(..)));
            assert_eq!(
                nox::sequential::reduce_cached(
                    &mut ar,
                    object,
                    formula,
                    expected.cost,
                    nox::sequential::Limits {
                        max_frames: expected.peak - 1
                    }
                )
                .unwrap_err(),
                nox::sequential::Error::Frames
            );
        }
    }
}

#[test]
fn canonical_field_boundaries_and_large_valid_word_shifts_match_native() {
    for tag in [5, 6, 7, 8, 9, 10, 14] {
        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 tag == 8 {
                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 memory = import(&ar);
            let evals = verified(&memory, &records);
            let last = *records.last().unwrap();
            assert_eq!(evals.bind_last(claim(&ar, last)).unwrap().remaining(), 0);
        }
    }
}

#[test]
fn axis_zero_and_hash_have_distinct_native_results_and_logical_step_counts() {
    let mut ar = Arena::try_new_boxed().unwrap();
    let object = atom(&mut ar, 42);
    let zero = atom(&mut ar, 0);
    let axis = op(&mut ar, 0, zero);
    let quote = op(&mut ar, 1, object);
    let hash = op(&mut ar, 15, quote);
    let mut records = Vec::new();
    let a = derive(&mut ar, object, axis, &mut records);
    let h = derive(&mut ar, object, hash, &mut records);
    assert_ne!(
        particle(&ar, records[a as usize].candidate.result),
        particle(&ar, records[h as usize].candidate.result)
    );
    let memory = import(&ar);
    let evals = verified(&memory, &records);
    assert_eq!(
        (evals.get(a).unwrap().cost(), evals.get(a).unwrap().steps()),
        (1, 2)
    );
    assert_eq!(
        (evals.get(h).unwrap().cost(), evals.get(h).unwrap().steps()),
        (26, 4)
    );
}

#[test]
fn repeated_prior_premises_count_expanded_occurrences_and_match_observer() {
    use nox::sequential::{CompactionLimits, observe::*};
    struct Counter {
        enters: u64,
        steps: u64,
    }
    impl Observer for Counter {
        type Error = core::convert::Infallible;
        fn record(&mut self, event: Event) -> Result<(), Self::Error> {
            if let Event::Transition(t) = event {
                self.enters += u64::from(matches!(t.before, LogicalAction::Enter { .. }));
            }
            if let Event::Completed { steps, .. } = event {
                self.steps = steps;
            }
            Ok(())
        }
    }
    let mut ar = Arena::try_new_boxed().unwrap();
    let object = atom(&mut ar, 0);
    let q = quote(&mut ar, 7);
    let f = binary(&mut ar, 3, q, q);
    let mut records = Vec::new();
    derive(&mut ar, object, f, &mut records);
    let mut root = records[2];
    root.candidate.premises = Premises::Two([0, 0]);
    let memory = import(&ar);
    let evals = verified(&memory, &[records[0], root]);
    let got = evals.get(1).unwrap();
    assert_eq!(
        (
            got.cost(),
            got.occurrences(),
            got.peak_frames(),
            got.steps()
        ),
        (3, 3, 2, 6)
    );
    let mut counter = Counter {
        enters: 0,
        steps: 0,
    };
    let run = reduce_compacting_observed_controlled(
        &mut ar,
        object,
        f,
        3,
        CompactionLimits {
            max_frames: 2,
            max_total_allocations: 10_000,
            max_collection_work: 10_000_000,
        },
        CaptureLimits {
            max_events: 10_000,
            max_bytes: 1_000_000,
            max_work: 100_000,
        },
        &mut counter,
        &mut || false,
    )
    .unwrap();
    assert_eq!((counter.enters, counter.steps), (3, 6));
    assert_eq!(run.execution.stats.evaluator_checkpoints, 7);
}

#[test]
fn saturated_and_dynamic_unselected_metadata_preserves_cheap_execution() {
    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);
    }
    assert_eq!(
        ar.get(huge).unwrap().bound,
        nox::data::Cost::Exact(u64::MAX)
    );
    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 f = binary(&mut ar, 5, cheap, cheap);
        let unary = op(&mut ar, 13, cheap);
        for formula in [f, unary] {
            let mut records = Vec::new();
            let root = derive(&mut ar, object, formula, &mut records);
            let expected = records[root as usize];
            let memory = import(&ar);
            let evals = verified(&memory, &records);
            assert_eq!(
                evals.bind_last(claim(&ar, expected)).unwrap().remaining(),
                0
            );
            for budget in [expected.cost, expected.cost + 1, u64::MAX] {
                let run = nox::sequential::reduce_cached(
                    &mut ar,
                    object,
                    formula,
                    budget,
                    nox::sequential::Limits {
                        max_frames: expected.peak,
                    },
                )
                .unwrap();
                assert!(matches!(run.outcome, Outcome::Ok(_, r) if r == budget - expected.cost));
            }
        }
    }
}

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/stream/tests/differential.rs

Graph