pub struct BinaryRelation<A: Ord, B: Ord> { /* private fields */ }Expand description
Finite binary relation type. A finite binary relation.
The starter implementation stores pairs in a BTreeSet so iteration order
is deterministic.
Composition direction is:
r.compose(&s) = { (a, c) | exists b. (a, b) in r and (b, c) in s }
§Examples
use relmath::{BinaryRelation, UnaryRelation};
let user_role = BinaryRelation::from_pairs([
("ann", "admin"),
("bob", "reviewer"),
]);
let extra_role = BinaryRelation::from_pairs([
("bob", "reviewer"),
("cara", "guest"),
]);
let role_permission = BinaryRelation::from_pairs([
("admin", "read"),
("reviewer", "approve"),
("guest", "view"),
]);
assert_eq!(
user_role.union(&extra_role).to_vec(),
vec![("ann", "admin"), ("bob", "reviewer"), ("cara", "guest")]
);
assert_eq!(
user_role.intersection(&extra_role).to_vec(),
vec![("bob", "reviewer")]
);
assert_eq!(user_role.difference(&extra_role).to_vec(), vec![("ann", "admin")]);
assert_eq!(
user_role.converse().to_vec(),
vec![("admin", "ann"), ("reviewer", "bob")]
);
let effective_permission = user_role.union(&extra_role).compose(&role_permission);
assert!(effective_permission.contains(&"ann", &"read"));
assert_eq!(
effective_permission.iter().copied().collect::<Vec<_>>(),
vec![("ann", "read"), ("bob", "approve"), ("cara", "view")]
);
assert_eq!(
effective_permission.domain().to_vec(),
vec!["ann", "bob", "cara"]
);
assert_eq!(
effective_permission.range().to_vec(),
vec!["approve", "read", "view"]
);
assert_eq!(
effective_permission
.restrict_domain(&UnaryRelation::from_values(["ann", "cara"]))
.to_vec(),
vec![("ann", "read"), ("cara", "view")]
);
assert_eq!(
effective_permission
.restrict_range(&UnaryRelation::from_values(["read", "view"]))
.to_vec(),
vec![("ann", "read"), ("cara", "view")]
);
assert_eq!(
effective_permission.image(&UnaryRelation::singleton("bob")).to_vec(),
vec!["approve"]
);
assert_eq!(
effective_permission
.preimage(&UnaryRelation::from_values(["read", "view"]))
.to_vec(),
vec!["ann", "cara"]
);Implementations§
Source§impl<A: Ord, B: Ord> BinaryRelation<A, B>
impl<A: Ord, B: Ord> BinaryRelation<A, B>
Sourcepub fn from_pairs<I>(pairs: I) -> Selfwhere
I: IntoIterator<Item = (A, B)>,
pub fn from_pairs<I>(pairs: I) -> Selfwhere
I: IntoIterator<Item = (A, B)>,
Creates a binary relation from the provided pairs.
Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([
7 ("Draft", "Review"),
8 ("Review", "Approved"),
9 ("Review", "Rejected"),
10 ]);
11
12 let states =
13 UnaryRelation::from_values(["Draft", "Review", "Approved", "Rejected", "Archived"]);
14 let reachable = step.reflexive_transitive_closure(&states);
15 let draft = UnaryRelation::singleton("Draft");
16
17 assert!(reachable.contains(&"Archived", &"Archived"));
18 assert!(reachable.contains(&"Draft", &"Approved"));
19
20 println!(
21 "reachable from Draft: {:?}",
22 reachable.image(&draft).to_vec()
23 );
24}More examples
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}5fn main() {
6 let user_role = BinaryRelation::from_pairs([
7 ("ann", "admin"),
8 ("bob", "analyst"),
9 ("bob", "reviewer"),
10 ("cara", "guest"),
11 ]);
12
13 let role_permission = BinaryRelation::from_pairs([
14 ("admin", "read"),
15 ("admin", "write"),
16 ("admin", "deploy"),
17 ("analyst", "read"),
18 ("reviewer", "approve"),
19 ("guest", "read"),
20 ]);
21
22 let effective_permission = user_role.compose(&role_permission);
23 let bob = UnaryRelation::singleton("bob");
24 let bob_permissions = effective_permission.image(&bob);
25
26 assert!(effective_permission.contains(&"ann", &"deploy"));
27 assert!(bob_permissions.contains(&"approve"));
28 assert!(bob_permissions.contains(&"read"));
29
30 println!(
31 "effective permissions for bob: {:?}",
32 bob_permissions.to_vec()
33 );
34}9fn main() -> Result<(), relmath::NaryRelationError> {
10 let people = UnaryRelation::from_values(["Ada", "Bob"]);
11 let parent = BinaryRelation::from_pairs([("Ada", "Bob"), ("Bob", "Cara")]);
12 let enrollments =
13 NaryRelation::from_rows(["student", "course"], [["Ada", "Math"], ["Bob", "Physics"]])?;
14
15 assert_eq!(tuple_count(&people), 2);
16 assert_eq!(tuple_count(&parent), 2);
17 assert_eq!(tuple_count(&enrollments), 2);
18
19 assert_eq!(
20 people.tuples().copied().collect::<Vec<_>>(),
21 vec!["Ada", "Bob"]
22 );
23 assert_eq!(
24 parent.tuples().copied().collect::<Vec<_>>(),
25 vec![("Ada", "Bob"), ("Bob", "Cara")]
26 );
27 assert_eq!(
28 enrollments
29 .tuples()
30 .map(|row| row.to_vec())
31 .collect::<Vec<_>>(),
32 vec![vec!["Ada", "Math"], vec!["Bob", "Physics"]]
33 );
34
35 println!("people: {:?}", people.tuples().copied().collect::<Vec<_>>());
36 println!("parent: {:?}", parent.tuples().copied().collect::<Vec<_>>());
37 println!(
38 "enrollments: {:?}",
39 enrollments
40 .tuples()
41 .map(|row| row.to_vec())
42 .collect::<Vec<_>>()
43 );
44
45 Ok(())
46}5fn main() {
6 let gene_disease = ProvenanceRelation::from_facts([
7 (("BRCA1", "BreastCancer"), "curated_panel"),
8 (("BRCA1", "BreastCancer"), "paper_12"),
9 (("TP53", "BreastCancer"), "paper_77"),
10 ]);
11
12 let disease_drug = relmath::BinaryRelation::from_pairs([
13 ("BreastCancer", "Olaparib"),
14 ("BreastCancer", "Tamoxifen"),
15 ]);
16
17 let supported_gene_disease = gene_disease.to_binary_relation();
18 let gene_drug = supported_gene_disease.compose(&disease_drug);
19 let brca1 = UnaryRelation::singleton("BRCA1");
20 let brca1_witness = gene_disease
21 .why(&("BRCA1", "BreastCancer"))
22 .expect("expected explanation");
23
24 assert_eq!(
25 gene_drug.image(&brca1).to_vec(),
26 vec!["Olaparib", "Tamoxifen"]
27 );
28 assert_eq!(brca1_witness.to_vec(), vec!["curated_panel", "paper_12"]);
29 assert!(brca1_witness.contains_token(&"paper_12"));
30 assert_eq!(
31 gene_disease
32 .provenance_of(&("BRCA1", "BreastCancer"))
33 .expect("expected explanation")
34 .to_vec(),
35 brca1_witness.to_vec()
36 );
37 assert_eq!(
38 gene_disease.support().to_vec(),
39 vec![("BRCA1", "BreastCancer"), ("TP53", "BreastCancer")]
40 );
41 assert!(gene_disease.why(&("BRCA1", "Olaparib")).is_none());
42
43 println!(
44 "why BRCA1 links to BreastCancer in the base evidence: {:?}",
45 brca1_witness.to_vec()
46 );
47}5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn insert(&mut self, left: A, right: B) -> bool
pub fn insert(&mut self, left: A, right: B) -> bool
Inserts a pair into the relation.
Returns true when the pair was not already present.
Sourcepub fn contains(&self, left: &A, right: &B) -> bool
pub fn contains(&self, left: &A, right: &B) -> bool
Returns true when the relation contains the given pair.
Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([
7 ("Draft", "Review"),
8 ("Review", "Approved"),
9 ("Review", "Rejected"),
10 ]);
11
12 let states =
13 UnaryRelation::from_values(["Draft", "Review", "Approved", "Rejected", "Archived"]);
14 let reachable = step.reflexive_transitive_closure(&states);
15 let draft = UnaryRelation::singleton("Draft");
16
17 assert!(reachable.contains(&"Archived", &"Archived"));
18 assert!(reachable.contains(&"Draft", &"Approved"));
19
20 println!(
21 "reachable from Draft: {:?}",
22 reachable.image(&draft).to_vec()
23 );
24}More examples
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}5fn main() {
6 let user_role = BinaryRelation::from_pairs([
7 ("ann", "admin"),
8 ("bob", "analyst"),
9 ("bob", "reviewer"),
10 ("cara", "guest"),
11 ]);
12
13 let role_permission = BinaryRelation::from_pairs([
14 ("admin", "read"),
15 ("admin", "write"),
16 ("admin", "deploy"),
17 ("analyst", "read"),
18 ("reviewer", "approve"),
19 ("guest", "read"),
20 ]);
21
22 let effective_permission = user_role.compose(&role_permission);
23 let bob = UnaryRelation::singleton("bob");
24 let bob_permissions = effective_permission.image(&bob);
25
26 assert!(effective_permission.contains(&"ann", &"deploy"));
27 assert!(bob_permissions.contains(&"approve"));
28 assert!(bob_permissions.contains(&"read"));
29
30 println!(
31 "effective permissions for bob: {:?}",
32 bob_permissions.to_vec()
33 );
34}5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn iter(&self) -> impl Iterator<Item = &(A, B)>
pub fn iter(&self) -> impl Iterator<Item = &(A, B)>
Returns an iterator over the stored pairs in deterministic order.
Sourcepub fn domain(&self) -> UnaryRelation<A>where
A: Clone,
pub fn domain(&self) -> UnaryRelation<A>where
A: Clone,
Returns the domain of the relation.
Sourcepub fn range(&self) -> UnaryRelation<B>where
B: Clone,
pub fn range(&self) -> UnaryRelation<B>where
B: Clone,
Returns the range of the relation.
Sourcepub fn converse(&self) -> BinaryRelation<B, A>
pub fn converse(&self) -> BinaryRelation<B, A>
Returns the converse relation.
Sourcepub fn intersection(&self, other: &Self) -> Self
pub fn intersection(&self, other: &Self) -> Self
Returns the intersection of self and other.
Sourcepub fn difference(&self, other: &Self) -> Self
pub fn difference(&self, other: &Self) -> Self
Returns the set difference self \ other.
Sourcepub fn restrict_domain(&self, allowed: &UnaryRelation<A>) -> Self
pub fn restrict_domain(&self, allowed: &UnaryRelation<A>) -> Self
Restricts the domain of the relation to allowed.
Sourcepub fn restrict_range(&self, allowed: &UnaryRelation<B>) -> Self
pub fn restrict_range(&self, allowed: &UnaryRelation<B>) -> Self
Restricts the range of the relation to allowed.
Sourcepub fn image(&self, sources: &UnaryRelation<A>) -> UnaryRelation<B>where
B: Clone,
pub fn image(&self, sources: &UnaryRelation<A>) -> UnaryRelation<B>where
B: Clone,
Computes the image of sources through the relation.
Returns { b | exists a in sources. (a, b) in self }.
Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([
7 ("Draft", "Review"),
8 ("Review", "Approved"),
9 ("Review", "Rejected"),
10 ]);
11
12 let states =
13 UnaryRelation::from_values(["Draft", "Review", "Approved", "Rejected", "Archived"]);
14 let reachable = step.reflexive_transitive_closure(&states);
15 let draft = UnaryRelation::singleton("Draft");
16
17 assert!(reachable.contains(&"Archived", &"Archived"));
18 assert!(reachable.contains(&"Draft", &"Approved"));
19
20 println!(
21 "reachable from Draft: {:?}",
22 reachable.image(&draft).to_vec()
23 );
24}More examples
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}5fn main() {
6 let user_role = BinaryRelation::from_pairs([
7 ("ann", "admin"),
8 ("bob", "analyst"),
9 ("bob", "reviewer"),
10 ("cara", "guest"),
11 ]);
12
13 let role_permission = BinaryRelation::from_pairs([
14 ("admin", "read"),
15 ("admin", "write"),
16 ("admin", "deploy"),
17 ("analyst", "read"),
18 ("reviewer", "approve"),
19 ("guest", "read"),
20 ]);
21
22 let effective_permission = user_role.compose(&role_permission);
23 let bob = UnaryRelation::singleton("bob");
24 let bob_permissions = effective_permission.image(&bob);
25
26 assert!(effective_permission.contains(&"ann", &"deploy"));
27 assert!(bob_permissions.contains(&"approve"));
28 assert!(bob_permissions.contains(&"read"));
29
30 println!(
31 "effective permissions for bob: {:?}",
32 bob_permissions.to_vec()
33 );
34}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}5fn main() {
6 let gene_disease = ProvenanceRelation::from_facts([
7 (("BRCA1", "BreastCancer"), "curated_panel"),
8 (("BRCA1", "BreastCancer"), "paper_12"),
9 (("TP53", "BreastCancer"), "paper_77"),
10 ]);
11
12 let disease_drug = relmath::BinaryRelation::from_pairs([
13 ("BreastCancer", "Olaparib"),
14 ("BreastCancer", "Tamoxifen"),
15 ]);
16
17 let supported_gene_disease = gene_disease.to_binary_relation();
18 let gene_drug = supported_gene_disease.compose(&disease_drug);
19 let brca1 = UnaryRelation::singleton("BRCA1");
20 let brca1_witness = gene_disease
21 .why(&("BRCA1", "BreastCancer"))
22 .expect("expected explanation");
23
24 assert_eq!(
25 gene_drug.image(&brca1).to_vec(),
26 vec!["Olaparib", "Tamoxifen"]
27 );
28 assert_eq!(brca1_witness.to_vec(), vec!["curated_panel", "paper_12"]);
29 assert!(brca1_witness.contains_token(&"paper_12"));
30 assert_eq!(
31 gene_disease
32 .provenance_of(&("BRCA1", "BreastCancer"))
33 .expect("expected explanation")
34 .to_vec(),
35 brca1_witness.to_vec()
36 );
37 assert_eq!(
38 gene_disease.support().to_vec(),
39 vec![("BRCA1", "BreastCancer"), ("TP53", "BreastCancer")]
40 );
41 assert!(gene_disease.why(&("BRCA1", "Olaparib")).is_none());
42
43 println!(
44 "why BRCA1 links to BreastCancer in the base evidence: {:?}",
45 brca1_witness.to_vec()
46 );
47}8fn main() {
9 let assignments = ValidTimeRelation::from_facts([
10 (
11 ("alice", "review"),
12 Interval::new(1, 3).expect("expected valid interval"),
13 ),
14 (
15 ("alice", "review"),
16 Interval::new(3, 5).expect("expected valid interval"),
17 ),
18 (
19 ("bob", "approve"),
20 Interval::new(2, 4).expect("expected valid interval"),
21 ),
22 ]);
23
24 let alice = UnaryRelation::singleton("alice");
25 let fact_support = assignments.support();
26 let exact_support = assignments.to_binary_relation();
27 let audit_window = Interval::new(2, 4).expect("expected valid interval");
28 let active_at_three = assignments.snapshot_at(&3);
29 let audit_assignments = assignments.restrict_to(&audit_window);
30
31 assert_eq!(
32 assignments
33 .valid_time_of(&("alice", "review"))
34 .expect("expected support")
35 .to_vec(),
36 vec![Interval::new(1, 5).expect("expected valid interval")]
37 );
38 assert!(assignments.is_active_at(&("alice", "review"), &4));
39 assert!(!assignments.is_active_at(&("alice", "review"), &5));
40 assert_eq!(
41 active_at_three.to_vec(),
42 vec![("alice", "review"), ("bob", "approve")]
43 );
44 assert_eq!(
45 fact_support.to_vec(),
46 vec![("alice", "review"), ("bob", "approve")]
47 );
48 assert_eq!(
49 audit_assignments
50 .valid_time_of(&("alice", "review"))
51 .expect("expected support")
52 .to_vec(),
53 vec![Interval::new(2, 4).expect("expected valid interval")]
54 );
55 assert_eq!(
56 audit_assignments.to_binary_relation().to_vec(),
57 vec![("alice", "review"), ("bob", "approve")]
58 );
59 assert_eq!(exact_support.image(&alice).to_vec(), vec!["review"]);
60
61 println!(
62 "fact support: {:?}; active at t=3: {:?}; audit restriction: {:?}",
63 fact_support.to_vec(),
64 active_at_three.to_vec(),
65 audit_assignments
66 .valid_time_of(&("alice", "review"))
67 .expect("expected support")
68 .to_vec()
69 );
70}Sourcepub fn preimage(&self, targets: &UnaryRelation<B>) -> UnaryRelation<A>where
A: Clone,
pub fn preimage(&self, targets: &UnaryRelation<B>) -> UnaryRelation<A>where
A: Clone,
Computes the preimage of targets through the relation.
Returns { a | exists b in targets. (a, b) in self }.
Sourcepub fn compose<C>(&self, rhs: &BinaryRelation<B, C>) -> BinaryRelation<A, C>
pub fn compose<C>(&self, rhs: &BinaryRelation<B, C>) -> BinaryRelation<A, C>
Composes self with rhs.
The result contains (a, c) whenever there exists b such that
(a, b) is in self and (b, c) is in rhs.
§Examples
use relmath::BinaryRelation;
let user_role = BinaryRelation::from_pairs([
("ann", "admin"),
("bob", "reviewer"),
]);
let role_permission = BinaryRelation::from_pairs([
("admin", "read"),
("reviewer", "approve"),
]);
let effective_permission = user_role.compose(&role_permission);
assert_eq!(
effective_permission.to_vec(),
vec![("ann", "read"), ("bob", "approve")]
);Examples found in repository?
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}More examples
5fn main() {
6 let user_role = BinaryRelation::from_pairs([
7 ("ann", "admin"),
8 ("bob", "analyst"),
9 ("bob", "reviewer"),
10 ("cara", "guest"),
11 ]);
12
13 let role_permission = BinaryRelation::from_pairs([
14 ("admin", "read"),
15 ("admin", "write"),
16 ("admin", "deploy"),
17 ("analyst", "read"),
18 ("reviewer", "approve"),
19 ("guest", "read"),
20 ]);
21
22 let effective_permission = user_role.compose(&role_permission);
23 let bob = UnaryRelation::singleton("bob");
24 let bob_permissions = effective_permission.image(&bob);
25
26 assert!(effective_permission.contains(&"ann", &"deploy"));
27 assert!(bob_permissions.contains(&"approve"));
28 assert!(bob_permissions.contains(&"read"));
29
30 println!(
31 "effective permissions for bob: {:?}",
32 bob_permissions.to_vec()
33 );
34}5fn main() {
6 let gene_disease = ProvenanceRelation::from_facts([
7 (("BRCA1", "BreastCancer"), "curated_panel"),
8 (("BRCA1", "BreastCancer"), "paper_12"),
9 (("TP53", "BreastCancer"), "paper_77"),
10 ]);
11
12 let disease_drug = relmath::BinaryRelation::from_pairs([
13 ("BreastCancer", "Olaparib"),
14 ("BreastCancer", "Tamoxifen"),
15 ]);
16
17 let supported_gene_disease = gene_disease.to_binary_relation();
18 let gene_drug = supported_gene_disease.compose(&disease_drug);
19 let brca1 = UnaryRelation::singleton("BRCA1");
20 let brca1_witness = gene_disease
21 .why(&("BRCA1", "BreastCancer"))
22 .expect("expected explanation");
23
24 assert_eq!(
25 gene_drug.image(&brca1).to_vec(),
26 vec!["Olaparib", "Tamoxifen"]
27 );
28 assert_eq!(brca1_witness.to_vec(), vec!["curated_panel", "paper_12"]);
29 assert!(brca1_witness.contains_token(&"paper_12"));
30 assert_eq!(
31 gene_disease
32 .provenance_of(&("BRCA1", "BreastCancer"))
33 .expect("expected explanation")
34 .to_vec(),
35 brca1_witness.to_vec()
36 );
37 assert_eq!(
38 gene_disease.support().to_vec(),
39 vec![("BRCA1", "BreastCancer"), ("TP53", "BreastCancer")]
40 );
41 assert!(gene_disease.why(&("BRCA1", "Olaparib")).is_none());
42
43 println!(
44 "why BRCA1 links to BreastCancer in the base evidence: {:?}",
45 brca1_witness.to_vec()
46 );
47}Sourcepub fn to_vec(&self) -> Vec<(A, B)>
pub fn to_vec(&self) -> Vec<(A, B)>
Converts the relation into a sorted vector of pairs.
Examples found in repository?
10fn exact_pairs<R>(relation: &R) -> BinaryRelation<&'static str, &'static str>
11where
12 R: ExactSupport<(&'static str, &'static str)>
13 + ToExactBinaryRelation<&'static str, &'static str>,
14{
15 assert_eq!(
16 relation.exact_support().to_vec(),
17 relation.to_binary_relation().to_vec()
18 );
19 relation.to_binary_relation()
20}
21
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}More examples
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}8fn main() {
9 let assignments = ValidTimeRelation::from_facts([
10 (
11 ("alice", "review"),
12 Interval::new(1, 3).expect("expected valid interval"),
13 ),
14 (
15 ("alice", "review"),
16 Interval::new(3, 5).expect("expected valid interval"),
17 ),
18 (
19 ("bob", "approve"),
20 Interval::new(2, 4).expect("expected valid interval"),
21 ),
22 ]);
23
24 let alice = UnaryRelation::singleton("alice");
25 let fact_support = assignments.support();
26 let exact_support = assignments.to_binary_relation();
27 let audit_window = Interval::new(2, 4).expect("expected valid interval");
28 let active_at_three = assignments.snapshot_at(&3);
29 let audit_assignments = assignments.restrict_to(&audit_window);
30
31 assert_eq!(
32 assignments
33 .valid_time_of(&("alice", "review"))
34 .expect("expected support")
35 .to_vec(),
36 vec![Interval::new(1, 5).expect("expected valid interval")]
37 );
38 assert!(assignments.is_active_at(&("alice", "review"), &4));
39 assert!(!assignments.is_active_at(&("alice", "review"), &5));
40 assert_eq!(
41 active_at_three.to_vec(),
42 vec![("alice", "review"), ("bob", "approve")]
43 );
44 assert_eq!(
45 fact_support.to_vec(),
46 vec![("alice", "review"), ("bob", "approve")]
47 );
48 assert_eq!(
49 audit_assignments
50 .valid_time_of(&("alice", "review"))
51 .expect("expected support")
52 .to_vec(),
53 vec![Interval::new(2, 4).expect("expected valid interval")]
54 );
55 assert_eq!(
56 audit_assignments.to_binary_relation().to_vec(),
57 vec![("alice", "review"), ("bob", "approve")]
58 );
59 assert_eq!(exact_support.image(&alice).to_vec(), vec!["review"]);
60
61 println!(
62 "fact support: {:?}; active at t=3: {:?}; audit restriction: {:?}",
63 fact_support.to_vec(),
64 active_at_three.to_vec(),
65 audit_assignments
66 .valid_time_of(&("alice", "review"))
67 .expect("expected support")
68 .to_vec()
69 );
70}Source§impl<T: Ord> BinaryRelation<T, T>
impl<T: Ord> BinaryRelation<T, T>
Sourcepub fn carrier(&self) -> UnaryRelation<T>where
T: Clone,
pub fn carrier(&self) -> UnaryRelation<T>where
T: Clone,
Returns the carrier induced by the relation: domain union range.
This is support-derived carrier information, not an explicit
crate::FiniteCarrier. Use crate::FiniteCarrier when the declared
domain must remain visible even for disconnected values that do not
appear in stored pairs.
§Examples
use relmath::{BinaryRelation, FiniteCarrier};
let step = BinaryRelation::from_pairs([("Draft", "Review")]);
let explicit = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
assert_eq!(step.carrier().to_vec(), vec!["Draft", "Review"]);
assert_eq!(explicit.to_vec(), vec!["Archived", "Draft", "Review"]);Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn identity(carrier: &UnaryRelation<T>) -> Selfwhere
T: Clone,
pub fn identity(carrier: &UnaryRelation<T>) -> Selfwhere
T: Clone,
Returns the identity relation on carrier.
§Examples
use relmath::{BinaryRelation, UnaryRelation};
let carrier = UnaryRelation::from_values(["Draft", "Review"]);
assert_eq!(
BinaryRelation::identity(&carrier).to_vec(),
vec![("Draft", "Draft"), ("Review", "Review")]
);
// Use `identity_on` when the carrier should remain explicit.
let explicit = relmath::FiniteCarrier::from_values(["Draft", "Review"]);
assert_eq!(BinaryRelation::identity_on(&explicit).to_vec(), BinaryRelation::identity(&carrier).to_vec());Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn identity_on(carrier: &FiniteCarrier<T>) -> Selfwhere
T: Clone,
pub fn identity_on(carrier: &FiniteCarrier<T>) -> Selfwhere
T: Clone,
Returns the identity relation on an explicit finite carrier.
This is the G7 carrier-aware companion to Self::identity. It keeps
the carrier explicit at the API boundary instead of first converting it
into a unary relation.
§Examples
use relmath::{BinaryRelation, FiniteCarrier, UnaryRelation};
let carrier = FiniteCarrier::from_values(["Draft", "Review"]);
let unary = UnaryRelation::from_values(["Draft", "Review"]);
assert_eq!(
BinaryRelation::identity_on(&carrier).to_vec(),
vec![("Draft", "Draft"), ("Review", "Review")]
);
assert_eq!(
BinaryRelation::identity_on(&carrier).to_vec(),
BinaryRelation::identity(&unary).to_vec()
);Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn transitive_closure(&self) -> Selfwhere
T: Clone,
pub fn transitive_closure(&self) -> Selfwhere
T: Clone,
Computes the transitive closure of the relation.
§Examples
use relmath::BinaryRelation;
let step = BinaryRelation::from_pairs([
("Draft", "Review"),
("Review", "Approved"),
]);
assert_eq!(
step.transitive_closure().to_vec(),
vec![
("Draft", "Approved"),
("Draft", "Review"),
("Review", "Approved"),
]
);Sourcepub fn reflexive_transitive_closure(&self, carrier: &UnaryRelation<T>) -> Selfwhere
T: Clone,
pub fn reflexive_transitive_closure(&self, carrier: &UnaryRelation<T>) -> Selfwhere
T: Clone,
Computes the reflexive-transitive closure on the given carrier.
Values that appear in carrier but not in any pair still gain their
identity edge in the result.
§Examples
use relmath::{BinaryRelation, UnaryRelation};
let step = BinaryRelation::from_pairs([("Draft", "Review")]);
let states = UnaryRelation::from_values(["Draft", "Review", "Archived"]);
let reachable = step.reflexive_transitive_closure(&states);
assert!(reachable.contains(&"Archived", &"Archived"));
assert!(reachable.contains(&"Draft", &"Review"));
let explicit_states = relmath::FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
assert_eq!(
step.reflexive_transitive_closure_on(&explicit_states).to_vec(),
reachable.to_vec()
);Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([
7 ("Draft", "Review"),
8 ("Review", "Approved"),
9 ("Review", "Rejected"),
10 ]);
11
12 let states =
13 UnaryRelation::from_values(["Draft", "Review", "Approved", "Rejected", "Archived"]);
14 let reachable = step.reflexive_transitive_closure(&states);
15 let draft = UnaryRelation::singleton("Draft");
16
17 assert!(reachable.contains(&"Archived", &"Archived"));
18 assert!(reachable.contains(&"Draft", &"Approved"));
19
20 println!(
21 "reachable from Draft: {:?}",
22 reachable.image(&draft).to_vec()
23 );
24}More examples
5fn main() {
6 let parent = BinaryRelation::from_pairs([
7 ("Ada", "Bob"),
8 ("Ada", "Cara"),
9 ("Bob", "Dana"),
10 ("Cara", "Eli"),
11 ("Dana", "Finn"),
12 ]);
13
14 let people = UnaryRelation::from_values(["Ada", "Bob", "Cara", "Dana", "Eli", "Finn"]);
15 let grandparent = parent.compose(&parent);
16 let ancestor = parent.reflexive_transitive_closure(&people);
17
18 let ada = UnaryRelation::singleton("Ada");
19 let reachable_from_ada = ancestor.image(&ada);
20
21 assert!(grandparent.contains(&"Ada", &"Dana"));
22 assert!(grandparent.contains(&"Ada", &"Eli"));
23 assert!(reachable_from_ada.contains(&"Finn"));
24
25 println!("grandparent pairs: {:?}", grandparent.to_vec());
26 println!(
27 "people reachable from Ada: {:?}",
28 reachable_from_ada.to_vec()
29 );
30}5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn reflexive_transitive_closure_on(
&self,
carrier: &FiniteCarrier<T>,
) -> Selfwhere
T: Clone,
pub fn reflexive_transitive_closure_on(
&self,
carrier: &FiniteCarrier<T>,
) -> Selfwhere
T: Clone,
Computes the reflexive-transitive closure on an explicit finite
carrier.
Values that appear in carrier but not in any pair still gain their
identity edge in the result.
This is the G7 carrier-aware companion to
Self::reflexive_transitive_closure.
§Examples
use relmath::{BinaryRelation, FiniteCarrier, UnaryRelation};
let step = BinaryRelation::from_pairs([("Draft", "Review")]);
let explicit_states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
let unary_states = UnaryRelation::from_values(["Draft", "Review", "Archived"]);
let reachable = step.reflexive_transitive_closure_on(&explicit_states);
assert!(reachable.contains(&"Archived", &"Archived"));
assert!(reachable.contains(&"Draft", &"Review"));
assert_eq!(reachable.to_vec(), step.reflexive_transitive_closure(&unary_states).to_vec());Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn is_reflexive(&self, carrier: &UnaryRelation<T>) -> bool
pub fn is_reflexive(&self, carrier: &UnaryRelation<T>) -> bool
Returns true when the relation is reflexive on carrier.
Use Self::is_reflexive_on when the carrier should remain explicit
as a crate::FiniteCarrier.
Sourcepub fn is_reflexive_on(&self, carrier: &FiniteCarrier<T>) -> bool
pub fn is_reflexive_on(&self, carrier: &FiniteCarrier<T>) -> bool
Returns true when the relation is reflexive on an explicit finite
carrier.
§Examples
use relmath::{BinaryRelation, FiniteCarrier};
let aliases = BinaryRelation::from_pairs([
("A. Smith", "A. Smith"),
("A. Smith", "Alice Smith"),
("Alice Smith", "A. Smith"),
("Alice Smith", "Alice Smith"),
]);
let carrier = FiniteCarrier::from_values(["A. Smith", "Alice Smith"]);
assert!(aliases.is_reflexive_on(&carrier));Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn is_irreflexive(&self, carrier: &UnaryRelation<T>) -> bool
pub fn is_irreflexive(&self, carrier: &UnaryRelation<T>) -> bool
Returns true when the relation is irreflexive on carrier.
Use Self::is_irreflexive_on when the carrier should remain explicit
as a crate::FiniteCarrier.
Sourcepub fn is_irreflexive_on(&self, carrier: &FiniteCarrier<T>) -> bool
pub fn is_irreflexive_on(&self, carrier: &FiniteCarrier<T>) -> bool
Returns true when the relation is irreflexive on an explicit finite
carrier.
§Examples
use relmath::{BinaryRelation, FiniteCarrier};
let step = BinaryRelation::from_pairs([("Draft", "Review")]);
let carrier = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
assert!(step.is_irreflexive_on(&carrier));Examples found in repository?
5fn main() {
6 let step = BinaryRelation::from_pairs([("Draft", "Review")]);
7 let states = FiniteCarrier::from_values(["Draft", "Review", "Archived"]);
8
9 let inferred = step.carrier();
10 let inferred_identity = BinaryRelation::identity(&inferred);
11 let explicit_identity = BinaryRelation::identity_on(&states);
12 let reachable = step.reflexive_transitive_closure_on(&states);
13
14 assert_eq!(inferred.to_vec(), vec!["Draft", "Review"]);
15 assert_eq!(
16 inferred_identity.to_vec(),
17 vec![("Draft", "Draft"), ("Review", "Review")]
18 );
19 assert_eq!(
20 explicit_identity.to_vec(),
21 vec![
22 ("Archived", "Archived"),
23 ("Draft", "Draft"),
24 ("Review", "Review"),
25 ]
26 );
27 assert_eq!(states.to_vec(), vec!["Archived", "Draft", "Review"]);
28 assert_eq!(
29 reachable.to_vec(),
30 step.reflexive_transitive_closure(&states.to_unary_relation())
31 .to_vec()
32 );
33 assert!(reachable.is_reflexive_on(&states));
34 assert!(step.is_irreflexive_on(&states));
35 assert!(reachable.contains(&"Archived", &"Archived"));
36 assert!(reachable.contains(&"Draft", &"Review"));
37
38 println!(
39 "explicit carrier: {:?}; inferred support: {:?}; inferred identity: {:?}; explicit identity: {:?}; reachable: {:?}",
40 states.to_vec(),
41 inferred.to_vec(),
42 inferred_identity.to_vec(),
43 explicit_identity.to_vec(),
44 reachable.to_vec()
45 );
46}Sourcepub fn is_symmetric(&self) -> bool
pub fn is_symmetric(&self) -> bool
Returns true when the relation is symmetric.
Sourcepub fn is_antisymmetric(&self) -> bool
pub fn is_antisymmetric(&self) -> bool
Returns true when the relation is antisymmetric.
Sourcepub fn is_transitive(&self) -> boolwhere
T: Clone,
pub fn is_transitive(&self) -> boolwhere
T: Clone,
Returns true when the relation is transitive.
Sourcepub fn is_equivalence(&self, carrier: &UnaryRelation<T>) -> boolwhere
T: Clone,
pub fn is_equivalence(&self, carrier: &UnaryRelation<T>) -> boolwhere
T: Clone,
Returns true when the relation is an equivalence relation on carrier.
§Examples
use relmath::{BinaryRelation, UnaryRelation};
let aliases = BinaryRelation::from_pairs([
("A. Smith", "A. Smith"),
("A. Smith", "Alice Smith"),
("Alice Smith", "A. Smith"),
("Alice Smith", "Alice Smith"),
]);
let carrier = UnaryRelation::from_values(["A. Smith", "Alice Smith"]);
assert!(aliases.is_equivalence(&carrier));
let explicit = relmath::FiniteCarrier::from_values(["A. Smith", "Alice Smith"]);
assert!(aliases.is_equivalence_on(&explicit));Sourcepub fn is_equivalence_on(&self, carrier: &FiniteCarrier<T>) -> boolwhere
T: Clone,
pub fn is_equivalence_on(&self, carrier: &FiniteCarrier<T>) -> boolwhere
T: Clone,
Returns true when the relation is an equivalence relation on an
explicit finite carrier.
§Examples
use relmath::{BinaryRelation, FiniteCarrier};
let aliases = BinaryRelation::from_pairs([
("A. Smith", "A. Smith"),
("A. Smith", "Alice Smith"),
("Alice Smith", "A. Smith"),
("Alice Smith", "Alice Smith"),
]);
let carrier = FiniteCarrier::from_values(["A. Smith", "Alice Smith"]);
assert!(aliases.is_equivalence_on(&carrier));Sourcepub fn is_partial_order(&self, carrier: &UnaryRelation<T>) -> boolwhere
T: Clone,
pub fn is_partial_order(&self, carrier: &UnaryRelation<T>) -> boolwhere
T: Clone,
Returns true when the relation is a partial order on carrier.
§Examples
use relmath::{BinaryRelation, UnaryRelation};
let divides = BinaryRelation::from_pairs([
(1_u8, 1_u8),
(1, 2),
(1, 4),
(2, 2),
(2, 4),
(4, 4),
]);
let carrier = UnaryRelation::from_values([1_u8, 2_u8, 4_u8]);
assert!(divides.is_partial_order(&carrier));
let explicit = relmath::FiniteCarrier::from_values([1_u8, 2_u8, 4_u8]);
assert!(divides.is_partial_order_on(&explicit));Sourcepub fn is_partial_order_on(&self, carrier: &FiniteCarrier<T>) -> boolwhere
T: Clone,
pub fn is_partial_order_on(&self, carrier: &FiniteCarrier<T>) -> boolwhere
T: Clone,
Returns true when the relation is a partial order on an explicit
finite carrier.
§Examples
use relmath::{BinaryRelation, FiniteCarrier};
let divides = BinaryRelation::from_pairs([
(1_u8, 1_u8),
(1, 2),
(1, 4),
(2, 2),
(2, 4),
(4, 4),
]);
let carrier = FiniteCarrier::from_values([1_u8, 2_u8, 4_u8]);
assert!(divides.is_partial_order_on(&carrier));Trait Implementations§
Source§impl<A: Clone + Ord, B: Clone + Ord> Clone for BinaryRelation<A, B>
impl<A: Clone + Ord, B: Clone + Ord> Clone for BinaryRelation<A, B>
Source§fn clone(&self) -> BinaryRelation<A, B>
fn clone(&self) -> BinaryRelation<A, B>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<A: Ord, B: Ord> Extend<(A, B)> for BinaryRelation<A, B>
impl<A: Ord, B: Ord> Extend<(A, B)> for BinaryRelation<A, B>
Source§fn extend<I: IntoIterator<Item = (A, B)>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = (A, B)>>(&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)