pub struct AnnotatedRelation<F: Ord, A: Semiring> { /* private fields */ }Expand description
Deterministic annotated facts over a semiring-like annotation domain.
AnnotatedRelation<F, A> stores at most one annotation per fact. Repeated
insertion of the same fact combines annotations by Semiring::add in
insertion order. Only non-zero annotations are stored, so exact support is
the set of facts whose current annotation is not zero.
Inserting a zero annotation for an absent fact does nothing. Inserting a
zero annotation for a present fact also leaves the stored annotation
unchanged because zero is the additive identity. If a custom annotation
domain combines to zero, the fact is removed from the annotated relation.
Unlike provenance in crate::provenance, the stored value is the
annotation itself rather than a witness or explanation set.
This first annotated relation slice focuses on deterministic storage, inspection, and exact support materialization. Annotated set algebra, annotated composition, temporal semantics, and broader uncertainty operators remain later work.
§Examples
use relmath::{
BinaryRelation,
annotated::{AnnotatedRelation, Semiring},
};
#[derive(Clone, Debug, PartialEq, Eq)]
struct Count(u8);
impl Semiring for Count {
fn zero() -> Self {
Self(0)
}
fn one() -> Self {
Self(1)
}
fn add(&self, rhs: &Self) -> Self {
Self(self.0.saturating_add(rhs.0))
}
fn mul(&self, rhs: &Self) -> Self {
Self(self.0.saturating_mul(rhs.0))
}
}
let mut assignments = AnnotatedRelation::new();
assert!(assignments.insert(("Alice", "Review"), Count(1)));
assert!(assignments.insert(("Alice", "Review"), Count(2)));
assert_eq!(
assignments.annotation_of(&("Alice", "Review")),
Some(&Count(3))
);
let support: BinaryRelation<_, _> = assignments.to_binary_relation();
assert_eq!(support.to_vec(), vec![("Alice", "Review")]);Implementations§
Source§impl<F: Ord, A: Semiring> AnnotatedRelation<F, A>
impl<F: Ord, A: Semiring> AnnotatedRelation<F, A>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty annotated relation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
use relmath::FiniteRelation;
let relation = AnnotatedRelation::<(&str, &str), BooleanSemiring>::new();
assert!(relation.is_empty());Sourcepub fn from_facts<I>(facts: I) -> Selfwhere
I: IntoIterator<Item = (F, A)>,
pub fn from_facts<I>(facts: I) -> Selfwhere
I: IntoIterator<Item = (F, A)>,
Creates an annotated relation from (fact, annotation) entries.
Repeated facts combine annotations by Semiring::add in iterator order.
Entries with zero annotations do not create stored support.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let relation = AnnotatedRelation::from_facts([
(("alice", "read"), BooleanSemiring::TRUE),
(("alice", "read"), BooleanSemiring::FALSE),
(("bob", "approve"), BooleanSemiring::FALSE),
]);
assert!(relation.contains_fact(&("alice", "read")));
assert!(!relation.contains_fact(&("bob", "approve")));Examples found in repository?
29fn main() {
30 let confirmations = AnnotatedRelation::from_facts([
31 (("Alice", "Math"), SupportCount(1)),
32 (("Alice", "Math"), SupportCount(1)),
33 (("Bob", "Physics"), SupportCount(1)),
34 (("Cara", "Logic"), SupportCount::zero()),
35 ]);
36
37 let exact_completed = confirmations.to_binary_relation();
38 let alice = UnaryRelation::singleton("Alice");
39
40 assert_eq!(
41 confirmations.annotation_of(&("Alice", "Math")),
42 Some(&SupportCount(2))
43 );
44 assert_eq!(exact_completed.image(&alice).to_vec(), vec!["Math"]);
45 assert!(!confirmations.contains_fact(&("Cara", "Logic")));
46 assert_eq!(
47 confirmations
48 .iter()
49 .map(|(fact, count)| (*fact, count.0))
50 .collect::<Vec<_>>(),
51 vec![(("Alice", "Math"), 2), (("Bob", "Physics"), 1)]
52 );
53
54 println!(
55 "stored support counts: {:?}",
56 confirmations
57 .iter()
58 .map(|(fact, count)| (*fact, count.0))
59 .collect::<Vec<_>>()
60 );
61}More examples
22fn main() {
23 let evidence = ProvenanceRelation::from_facts([
24 (("alice", "review"), "directory"),
25 (("bob", "approve"), "policy"),
26 ]);
27 let permissions = AnnotatedRelation::from_facts([
28 (("alice", "review"), BooleanSemiring::TRUE),
29 (("bob", "approve"), BooleanSemiring::TRUE),
30 ]);
31 let schedule = ValidTimeRelation::from_facts([
32 (
33 ("alice", "review"),
34 Interval::new(1, 3).expect("expected valid interval"),
35 ),
36 (
37 ("bob", "approve"),
38 Interval::new(2, 4).expect("expected valid interval"),
39 ),
40 ]);
41
42 let exact_evidence = exact_pairs(&evidence);
43 let exact_permissions = exact_pairs(&permissions);
44 let exact_schedule = exact_pairs(&schedule);
45
46 assert_eq!(
47 exact_evidence.to_vec(),
48 vec![("alice", "review"), ("bob", "approve")]
49 );
50 assert_eq!(exact_permissions.to_vec(), exact_evidence.to_vec());
51 assert_eq!(exact_schedule.to_vec(), exact_evidence.to_vec());
52
53 assert_eq!(
54 evidence
55 .why(&("alice", "review"))
56 .expect("expected witness")
57 .to_vec(),
58 vec!["directory"]
59 );
60 assert_eq!(
61 permissions.annotation_of(&("alice", "review")),
62 Some(&BooleanSemiring::TRUE)
63 );
64 assert_eq!(
65 schedule
66 .valid_time_of(&("alice", "review"))
67 .expect("expected interval support")
68 .to_vec(),
69 vec![Interval::new(1, 3).expect("expected valid interval")]
70 );
71
72 println!(
73 "witness={:?}, annotation={:?}, interval_support={:?}, exact_support={:?}",
74 evidence
75 .why(&("alice", "review"))
76 .expect("expected witness")
77 .to_vec(),
78 permissions.annotation_of(&("alice", "review")),
79 schedule
80 .valid_time_of(&("alice", "review"))
81 .expect("expected interval support")
82 .to_vec(),
83 exact_schedule.to_vec()
84 );
85}Sourcepub fn insert(&mut self, fact: F, annotation: A) -> bool
pub fn insert(&mut self, fact: F, annotation: A) -> bool
Inserts one annotation for a fact.
Returns true when the stored support or stored annotation changes.
Repeated facts combine as current.add(&annotation). Facts whose
resulting annotation is zero are removed from the relation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let mut relation = AnnotatedRelation::new();
assert!(!relation.insert(("alice", "read"), BooleanSemiring::FALSE));
assert!(relation.insert(("alice", "read"), BooleanSemiring::TRUE));
assert!(!relation.insert(("alice", "read"), BooleanSemiring::FALSE));
assert!(relation.contains_fact(&("alice", "read")));Sourcepub fn contains_fact(&self, fact: &F) -> bool
pub fn contains_fact(&self, fact: &F) -> bool
Returns true when the relation contains the given fact with a
non-zero annotation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let relation = AnnotatedRelation::from_facts([
(("alice", "read"), BooleanSemiring::TRUE),
(("bob", "approve"), BooleanSemiring::FALSE),
]);
assert!(relation.contains_fact(&("alice", "read")));
assert!(!relation.contains_fact(&("bob", "approve")));Examples found in repository?
29fn main() {
30 let confirmations = AnnotatedRelation::from_facts([
31 (("Alice", "Math"), SupportCount(1)),
32 (("Alice", "Math"), SupportCount(1)),
33 (("Bob", "Physics"), SupportCount(1)),
34 (("Cara", "Logic"), SupportCount::zero()),
35 ]);
36
37 let exact_completed = confirmations.to_binary_relation();
38 let alice = UnaryRelation::singleton("Alice");
39
40 assert_eq!(
41 confirmations.annotation_of(&("Alice", "Math")),
42 Some(&SupportCount(2))
43 );
44 assert_eq!(exact_completed.image(&alice).to_vec(), vec!["Math"]);
45 assert!(!confirmations.contains_fact(&("Cara", "Logic")));
46 assert_eq!(
47 confirmations
48 .iter()
49 .map(|(fact, count)| (*fact, count.0))
50 .collect::<Vec<_>>(),
51 vec![(("Alice", "Math"), 2), (("Bob", "Physics"), 1)]
52 );
53
54 println!(
55 "stored support counts: {:?}",
56 confirmations
57 .iter()
58 .map(|(fact, count)| (*fact, count.0))
59 .collect::<Vec<_>>()
60 );
61}Sourcepub fn annotation_of(&self, fact: &F) -> Option<&A>
pub fn annotation_of(&self, fact: &F) -> Option<&A>
Returns the stored annotation for one fact.
When a fact is absent, this returns None. Zero annotations are not
stored, so None also means there is no stored exact support for that
fact. Unlike crate::provenance::ProvenanceRelation::why, this
returns the stored annotation value itself rather than a witness set.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let relation = AnnotatedRelation::from_facts([
(("alice", "read"), BooleanSemiring::TRUE),
(("bob", "approve"), BooleanSemiring::FALSE),
]);
assert_eq!(
relation.annotation_of(&("alice", "read")),
Some(&BooleanSemiring::TRUE)
);
assert_eq!(relation.annotation_of(&("bob", "approve")), None);Examples found in repository?
29fn main() {
30 let confirmations = AnnotatedRelation::from_facts([
31 (("Alice", "Math"), SupportCount(1)),
32 (("Alice", "Math"), SupportCount(1)),
33 (("Bob", "Physics"), SupportCount(1)),
34 (("Cara", "Logic"), SupportCount::zero()),
35 ]);
36
37 let exact_completed = confirmations.to_binary_relation();
38 let alice = UnaryRelation::singleton("Alice");
39
40 assert_eq!(
41 confirmations.annotation_of(&("Alice", "Math")),
42 Some(&SupportCount(2))
43 );
44 assert_eq!(exact_completed.image(&alice).to_vec(), vec!["Math"]);
45 assert!(!confirmations.contains_fact(&("Cara", "Logic")));
46 assert_eq!(
47 confirmations
48 .iter()
49 .map(|(fact, count)| (*fact, count.0))
50 .collect::<Vec<_>>(),
51 vec![(("Alice", "Math"), 2), (("Bob", "Physics"), 1)]
52 );
53
54 println!(
55 "stored support counts: {:?}",
56 confirmations
57 .iter()
58 .map(|(fact, count)| (*fact, count.0))
59 .collect::<Vec<_>>()
60 );
61}More examples
22fn main() {
23 let evidence = ProvenanceRelation::from_facts([
24 (("alice", "review"), "directory"),
25 (("bob", "approve"), "policy"),
26 ]);
27 let permissions = AnnotatedRelation::from_facts([
28 (("alice", "review"), BooleanSemiring::TRUE),
29 (("bob", "approve"), BooleanSemiring::TRUE),
30 ]);
31 let schedule = ValidTimeRelation::from_facts([
32 (
33 ("alice", "review"),
34 Interval::new(1, 3).expect("expected valid interval"),
35 ),
36 (
37 ("bob", "approve"),
38 Interval::new(2, 4).expect("expected valid interval"),
39 ),
40 ]);
41
42 let exact_evidence = exact_pairs(&evidence);
43 let exact_permissions = exact_pairs(&permissions);
44 let exact_schedule = exact_pairs(&schedule);
45
46 assert_eq!(
47 exact_evidence.to_vec(),
48 vec![("alice", "review"), ("bob", "approve")]
49 );
50 assert_eq!(exact_permissions.to_vec(), exact_evidence.to_vec());
51 assert_eq!(exact_schedule.to_vec(), exact_evidence.to_vec());
52
53 assert_eq!(
54 evidence
55 .why(&("alice", "review"))
56 .expect("expected witness")
57 .to_vec(),
58 vec!["directory"]
59 );
60 assert_eq!(
61 permissions.annotation_of(&("alice", "review")),
62 Some(&BooleanSemiring::TRUE)
63 );
64 assert_eq!(
65 schedule
66 .valid_time_of(&("alice", "review"))
67 .expect("expected interval support")
68 .to_vec(),
69 vec![Interval::new(1, 3).expect("expected valid interval")]
70 );
71
72 println!(
73 "witness={:?}, annotation={:?}, interval_support={:?}, exact_support={:?}",
74 evidence
75 .why(&("alice", "review"))
76 .expect("expected witness")
77 .to_vec(),
78 permissions.annotation_of(&("alice", "review")),
79 schedule
80 .valid_time_of(&("alice", "review"))
81 .expect("expected interval support")
82 .to_vec(),
83 exact_schedule.to_vec()
84 );
85}Sourcepub fn iter(&self) -> impl Iterator<Item = (&F, &A)>
pub fn iter(&self) -> impl Iterator<Item = (&F, &A)>
Returns an iterator over facts and annotations in deterministic fact order.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let relation = AnnotatedRelation::from_facts([
(("alice", "admin"), BooleanSemiring::TRUE),
(("bob", "reviewer"), BooleanSemiring::TRUE),
]);
assert_eq!(
relation
.iter()
.map(|(fact, annotation)| (*fact, *annotation))
.collect::<Vec<_>>(),
vec![
(("alice", "admin"), BooleanSemiring::TRUE),
(("bob", "reviewer"), BooleanSemiring::TRUE),
]
);Examples found in repository?
29fn main() {
30 let confirmations = AnnotatedRelation::from_facts([
31 (("Alice", "Math"), SupportCount(1)),
32 (("Alice", "Math"), SupportCount(1)),
33 (("Bob", "Physics"), SupportCount(1)),
34 (("Cara", "Logic"), SupportCount::zero()),
35 ]);
36
37 let exact_completed = confirmations.to_binary_relation();
38 let alice = UnaryRelation::singleton("Alice");
39
40 assert_eq!(
41 confirmations.annotation_of(&("Alice", "Math")),
42 Some(&SupportCount(2))
43 );
44 assert_eq!(exact_completed.image(&alice).to_vec(), vec!["Math"]);
45 assert!(!confirmations.contains_fact(&("Cara", "Logic")));
46 assert_eq!(
47 confirmations
48 .iter()
49 .map(|(fact, count)| (*fact, count.0))
50 .collect::<Vec<_>>(),
51 vec![(("Alice", "Math"), 2), (("Bob", "Physics"), 1)]
52 );
53
54 println!(
55 "stored support counts: {:?}",
56 confirmations
57 .iter()
58 .map(|(fact, count)| (*fact, count.0))
59 .collect::<Vec<_>>()
60 );
61}Sourcepub fn support(&self) -> UnaryRelation<F>where
F: Clone,
pub fn support(&self) -> UnaryRelation<F>where
F: Clone,
Returns the exact support relation of stored facts as a unary relation.
This materialization forgets annotation values and keeps only which
facts are currently present with a non-zero annotation. Generic code
can access the same relation-level boundary through
crate::ExactSupport::exact_support.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let relation = AnnotatedRelation::from_facts([
(("alice", "admin"), BooleanSemiring::TRUE),
(("bob", "reviewer"), BooleanSemiring::TRUE),
(("bob", "reviewer"), BooleanSemiring::FALSE),
]);
assert_eq!(
relation.support().to_vec(),
vec![("alice", "admin"), ("bob", "reviewer")]
);Source§impl<T: Ord + Clone, A: Semiring> AnnotatedRelation<T, A>
impl<T: Ord + Clone, A: Semiring> AnnotatedRelation<T, A>
Sourcepub fn to_unary_relation(&self) -> UnaryRelation<T>
pub fn to_unary_relation(&self) -> UnaryRelation<T>
Converts scalar facts into a unary relation support set.
Generic code can access the same unary materialization boundary through
crate::ToExactUnaryRelation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let concepts = AnnotatedRelation::from_facts([
("Closure", BooleanSemiring::TRUE),
("Relations", BooleanSemiring::TRUE),
]);
assert_eq!(
concepts.to_unary_relation().to_vec(),
vec!["Closure", "Relations"]
);Source§impl<A0: Ord + Clone, B0: Ord + Clone, A: Semiring> AnnotatedRelation<(A0, B0), A>
impl<A0: Ord + Clone, B0: Ord + Clone, A: Semiring> AnnotatedRelation<(A0, B0), A>
Sourcepub fn to_binary_relation(&self) -> BinaryRelation<A0, B0>
pub fn to_binary_relation(&self) -> BinaryRelation<A0, B0>
Converts pair facts into a binary relation support set.
Generic code can access the same binary materialization boundary
through crate::ToExactBinaryRelation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let permissions = AnnotatedRelation::from_facts([
(("Alice", "read"), BooleanSemiring::TRUE),
(("Bob", "approve"), BooleanSemiring::TRUE),
]);
assert_eq!(
permissions.to_binary_relation().to_vec(),
vec![("Alice", "read"), ("Bob", "approve")]
);Examples found in repository?
29fn main() {
30 let confirmations = AnnotatedRelation::from_facts([
31 (("Alice", "Math"), SupportCount(1)),
32 (("Alice", "Math"), SupportCount(1)),
33 (("Bob", "Physics"), SupportCount(1)),
34 (("Cara", "Logic"), SupportCount::zero()),
35 ]);
36
37 let exact_completed = confirmations.to_binary_relation();
38 let alice = UnaryRelation::singleton("Alice");
39
40 assert_eq!(
41 confirmations.annotation_of(&("Alice", "Math")),
42 Some(&SupportCount(2))
43 );
44 assert_eq!(exact_completed.image(&alice).to_vec(), vec!["Math"]);
45 assert!(!confirmations.contains_fact(&("Cara", "Logic")));
46 assert_eq!(
47 confirmations
48 .iter()
49 .map(|(fact, count)| (*fact, count.0))
50 .collect::<Vec<_>>(),
51 vec![(("Alice", "Math"), 2), (("Bob", "Physics"), 1)]
52 );
53
54 println!(
55 "stored support counts: {:?}",
56 confirmations
57 .iter()
58 .map(|(fact, count)| (*fact, count.0))
59 .collect::<Vec<_>>()
60 );
61}Source§impl<T: Ord + Clone, A: Semiring> AnnotatedRelation<Vec<T>, A>
impl<T: Ord + Clone, A: Semiring> AnnotatedRelation<Vec<T>, A>
Sourcepub fn to_nary_relation<I, S>(
&self,
schema: I,
) -> Result<NaryRelation<T>, NaryRelationError>
pub fn to_nary_relation<I, S>( &self, schema: I, ) -> Result<NaryRelation<T>, NaryRelationError>
Converts row facts into an n-ary relation with the given schema.
The explicit schema preserves the current exact n-ary boundary where row
values do not themselves encode column names. This method reuses the
current NaryRelation validation rules, so duplicate or blank column
names and row-arity mismatches return NaryRelationError. Generic code
can access the same n-ary materialization boundary through
crate::ToExactNaryRelation.
§Examples
use relmath::annotated::{AnnotatedRelation, BooleanSemiring};
let completion = AnnotatedRelation::from_facts([
(vec!["Alice", "Math", "passed"], BooleanSemiring::TRUE),
(vec!["Bob", "Physics", "passed"], BooleanSemiring::TRUE),
]);
let relation = completion
.to_nary_relation(["student", "course", "status"])
.expect("expected valid support relation");
assert_eq!(
relation.to_rows(),
vec![
vec!["Alice", "Math", "passed"],
vec!["Bob", "Physics", "passed"],
]
);Trait Implementations§
Source§impl<F: Clone + Ord, A: Clone + Semiring> Clone for AnnotatedRelation<F, A>
impl<F: Clone + Ord, A: Clone + Semiring> Clone for AnnotatedRelation<F, A>
Source§fn clone(&self) -> AnnotatedRelation<F, A>
fn clone(&self) -> AnnotatedRelation<F, A>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<F: Ord + Clone, A: Semiring> ExactSupport<F> for AnnotatedRelation<F, A>
impl<F: Ord + Clone, A: Semiring> ExactSupport<F> for AnnotatedRelation<F, A>
Source§fn exact_support(&self) -> UnaryRelation<F>
fn exact_support(&self) -> UnaryRelation<F>
Source§impl<F: Ord, A: Semiring> Extend<(F, A)> for AnnotatedRelation<F, A>
impl<F: Ord, A: Semiring> Extend<(F, A)> for AnnotatedRelation<F, A>
Source§fn extend<I: IntoIterator<Item = (F, A)>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = (F, A)>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)