minerva 0.2.0

Causal ordering for distributed systems
//! Support exactness across the sparse product: a dot lives under exactly
//! one component, and every write path refuses the straddle (law 1 applied
//! across kinds, the `DotMap` cross-key discipline one level up).

use super::super::super::support::dot;
use crate::metis::{Anchor, Dot, DotSet, DotStore, Dotted, Kind, Locus};

use super::super::{TestNode, rank};
use super::{reg_block, seq_block};

#[test]
fn test_a_dot_lives_under_exactly_one_component() {
    let locus = Locus {
        anchor: Anchor::Origin,
        rank: rank(1),
    };

    // Tagged first: every other component refuses the same dot.
    let mut node = TestNode::new();
    assert!(node.write_tag(dot(1, 1), Kind::Sequence));
    assert!(!node.write_register(dot(1, 1), "x"));
    assert!(!node.weave(dot(1, 1), locus));
    assert!(!node.insert_child(7, reg_block(dot(1, 1), "x")));

    // Registered first: the tag, the sequence, and the map refuse it.
    let mut node = TestNode::new();
    assert!(node.write_register(dot(1, 2), "x"));
    assert!(!node.write_tag(dot(1, 2), Kind::Register));
    assert!(!node.weave(dot(1, 2), locus));
    assert!(!node.insert_child(7, seq_block(dot(1, 2), 1)));

    // Woven first: the scalar writes and the map refuse it.
    let mut node = TestNode::new();
    assert!(node.weave(dot(1, 3), locus));
    assert!(!node.write_tag(dot(1, 3), Kind::Sequence));
    assert!(!node.write_register(dot(1, 3), "x"));
    assert!(!node.insert_child(7, reg_block(dot(1, 3), "x")));

    // Held by a child (transitively): the parent's own components refuse it.
    let mut node = TestNode::new();
    assert!(node.insert_child(7, reg_block(dot(1, 4), "x")));
    assert!(!node.write_tag(dot(1, 4), Kind::Map));
    assert!(!node.write_register(dot(1, 4), "x"));
    assert!(!node.weave(dot(1, 4), locus));
}

#[test]
fn test_component_refusals_pass_through() {
    // The components' own refusals stay live under the node's methods: a
    // duplicate dot in the same component, and a bottom child. The non-dot 0
    // no longer needs an arm at any write door: the type carries the law, so
    // the refused state is unrepresentable (ruling R-91).
    let mut node = TestNode::new();
    assert!(Dot::from_parts(1, 0).is_err());
    assert!(!node.insert_child(7, TestNode::new()));

    assert!(node.write_tag(dot(1, 1), Kind::Register));
    assert!(!node.write_tag(dot(1, 1), Kind::Sequence));
}

#[test]
fn test_a_bottom_node_vanishes_from_its_parent_map() {
    // Canonical form at node grade: superseding everything under a child
    // whose content is scalar leaves the child bottom, and a bottom node has
    // no key (exactly the `DotMap` canonical-drop the recipe already had,
    // now covering the whole sparse product).
    let mut page: Dotted<TestNode> = Dotted::new();
    let delta = Dotted::from_store(super::page_with(7, reg_block(dot(1, 1), "x")));
    page.merge_from(&delta);
    assert!(page.store().children().get(&7).is_some());

    let mut superseded = DotSet::new();
    assert!(superseded.insert(dot(1, 1)));
    page.merge_from(&Dotted::from_context(superseded));
    assert!(page.store().children().get(&7).is_none());
    assert!(page.store().is_bottom());
}