-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathp82.re
35 lines (32 loc) · 810 Bytes
/
p82.re
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
/* Cycle from a given node. */
type graph_term('a) = {
nodes: list('a),
edges: list(('a, 'a))
};
let neighbors = (g, a, cond) => {
let edge = (l, (b, c)) =>
if (b == a && cond(c)) {
[c, ...l]
} else if (c == a && cond(b)) {
[b, ...l]
} else {
l
};
List.fold_left(edge, [], g.edges)
};
let rec list_path = (g, a, to_b) =>
switch to_b {
| [] => assert false /* [to_b] contains the path to [b]. */
| [a', ..._] =>
if (a' == a) {
[to_b]
} else {
let n = neighbors(g, a', (c) => ! List.mem(c, to_b));
List.concat(List.map((c) => list_path(g, a, [c, ...to_b]), n))
}
};
let cycles = (g, a) => {
let n = neighbors(g, a, (_) => true);
let p = List.concat(List.map((c) => list_path(g, a, [c]), n));
List.map((p) => p @ [a], p)
};