-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.rs
118 lines (101 loc) · 2.9 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use doublets::{data::LinkType, mem, unit, Doublets, Error, Link};
use doublets::{DoubletsExt, Links};
use tap::Pipe;
#[rustfmt::skip]
const CATALAN_NUMBERS: [u64; 25] = [
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012,
742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190,
6564120420, 24466267020, 91482563640, 343059613650, 1289904147324,
];
const fn catalan(n: usize) -> u64 {
CATALAN_NUMBERS[n]
}
fn spec_all_variants<T, S>(store: &mut S, seq: &[T]) -> Result<Vec<T>, Error<T>>
where
T: LinkType,
S: Doublets<T>,
{
assert!(seq.len() > 2);
let mut variants = Vec::with_capacity(catalan(seq.len() - 1) as usize);
for splitter in 1..seq.len() {
let (left, right) = seq.split_at(splitter);
let (left, right) = (
all_seq_variants(store, left)?,
all_seq_variants(store, right)?,
);
for from in left {
for &to in &right {
variants.push(store.get_or_create(from, to)?);
}
}
}
Ok(variants)
}
fn all_seq_variants<T, S>(store: &mut S, seq: &[T]) -> Result<Vec<T>, Error<T>>
where
T: LinkType,
S: Doublets<T>,
{
match seq {
&[single] => {
vec![single]
}
&[from, to] => {
vec![store.get_or_create(from, to)?]
}
seq => spec_all_variants(store, seq)?,
}
.pipe(Ok)
}
/// Performs a NAND operation on two boolean inputs.
///
/// # Arguments
///
/// * `a` - A boolean input.
/// * `b` - A boolean input.
///
/// # Returns
///
/// * A boolean output representing the NAND operation on the inputs.
fn nand(a: bool, b: bool) -> bool {
!(a && b)
}
fn get_link_by_id<T>(store: &mut unit::Store<usize, T>, id: usize) -> Result<Link<usize>, Error<usize>> {
// `any` constant denotes any link
let any = store.constants().any;
let mut link_result = Err(Error::new("Link not found"));
store.each_iter([id, any, any]).for_each(|link| {
if link.id() == id {
link_result = Ok(link);
}
});
link_result
}
fn main() -> Result<(), Error<usize>> {
let mem = mem::Global::new();
let mut store = unit::Store::<usize, _>::new(mem)?;
// Create a vector of N points using iterators
let seq: Vec<_> = (0..3)
.map(|_| store.create_point())
.collect::<Result<_, _>>()?;
let result = all_seq_variants(&mut store, &seq)?;
println!("{}", result.len());
println!("{}", result[0]);
// `any` constant denotes any link
let any = store.constants().any;
store.each_iter([any, any, any]).for_each(|link| {
println!("{link:?}");
});
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_nand() {
assert_eq!(nand(true, true), false);
assert_eq!(nand(true, false), true);
assert_eq!(nand(false, true), true);
assert_eq!(nand(false, false), true);
}
}