Expand description
relations – A basic crate for working with mathematical relations
The goal of this crate is to provide a basic and lightweight library for working with mathematical relations.
Relations
Mathematically, relations are sets of 2-tuples. Given a relation R and two items x and y, x and y are said to be R-related if (x, y) is contained in R.
Relations can be useful in the implementation of certain algorithms. Additionally, they can be used to model graphs.
This crate provides functionality for creating relations and working with them. In particular, there is functionality for testing properties of relations, such as testing whether a relation is transitive. Additionally, there is functionality for computing closures.
Scope of the Crate
This crate is not aiming to be feature complete or particularly feature rich. However, features additions of requests are always welcome.
Getting Started
There are two main exports in this crate:
The Relation
struct and the relation!
macro.
The former is the central object used to represent
relations. The latter provides convenient syntax
for denoting static relations.
Getting can be as easy as defining a relation using the relation! macro:
use relations::{relation, Relation};
let my_relation = relation!(
0 => 1,
1 => 2,
2 => 3
);
It is then easy to test whether items are related:
assert!(my_relation.are_related(&1, &2));
assert!(!my_relation.are_related(&0, &3));
assert!(!my_relation.are_related(&3, &4));
One can then use the provided methods to test things about the relation:
assert!(!my_relation.is_reflexive());
assert!(!my_relation.is_symmetric());
assert!(!my_relation.is_transitive());
assert!(my_relation.is_irreflexive());
assert!(my_relation.is_asymmetric());
assert!(my_relation.is_antisymmetric());
You can also compute closures of relations:
assert_eq!(
my_relation.reflexive_closure(),
relation!(0 => 1, 1 => 2, 2 => 3, 0 => 0, 1 => 1, 2 => 2, 3 => 3)
);
assert_eq!(
my_relation.symmetric_closure(),
relation!(0 => 1, 1 => 2, 2 => 3, 1 => 0, 2 => 1, 3 => 2)
);
assert_eq!(
my_relation.transitive_closure(),
relation!(0 => 1, 0 => 2, 0 => 3, 1 => 2, 1 => 3, 2 => 3)
);
It is also possible to define relations containing non-numerical items:
use relations::{relation, Relation};
let my_string_relation = relation!(
"a" => "b",
"b" => "c",
"c" => "d"
);
If you need to define relations dynamically, you can create them from iterators:
use relations::{Relation, relation};
let my_relation = Relation::from_iter((1..=10).map(|x| (x, x)));
assert_eq!(
my_relation,
relation!(
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10
)
);
Macros
Structs
Eq
, Hash
, Clone
, and Debug
.