1#![allow(dead_code)]
5
6#[derive(Clone, Debug)]
7pub struct INet {
8 pub nodes: Vec<u32>,
9 pub reuse: Vec<u32>,
10 pub rules: u32,
11}
12
13pub const ERA : u32 = 0;
15pub const CON : u32 = 1;
16pub const ANN : u32 = 2;
17pub const DUP : u32 = 3;
18pub const EQL : u32 = 0xFFFFFFFF;
19
20pub const ROOT : u32 = 1;
22
23pub type Port = u32;
25
26pub fn new_inet() -> INet {
28 INet {
29 nodes: vec![2,1,0,0], reuse: vec![],
31 rules: 0
32 }
33}
34
35pub fn new_node(inet: &mut INet, kind: u32) -> u32 {
37 let node : u32 = match inet.reuse.pop() {
38 Some(index) => index,
39 None => {
40 let len = inet.nodes.len();
41 inet.nodes.resize(len + 4, 0);
42 (len as u32) / 4
43 }
44 };
45 inet.nodes[port(node, 0) as usize] = port(node, 0);
46 inet.nodes[port(node, 1) as usize] = port(node, 1);
47 inet.nodes[port(node, 2) as usize] = port(node, 2);
48 inet.nodes[port(node, 3) as usize] = kind;
49 return node;
50}
51
52pub fn port(node: u32, slot: u32) -> Port {
54 (node << 2) | slot
55}
56
57pub fn addr(port: Port) -> u32 {
59 port >> 2
60}
61
62pub fn slot(port: Port) -> u32 {
64 port & 3
65}
66
67pub fn enter(inet: &INet, port: Port) -> Port {
69 inet.nodes[port as usize]
70}
71
72pub fn kind(inet: &INet, node: u32) -> u32 {
77 inet.nodes[port(node, 3) as usize]
78}
79
80pub fn link(inet: &mut INet, ptr_a: u32, ptr_b: u32) {
82 inet.nodes[ptr_a as usize] = ptr_b;
83 inet.nodes[ptr_b as usize] = ptr_a;
84}
85
86pub fn reduce(inet: &mut INet, prev: Port) -> Port {
88 let mut path = vec![];
89 let mut prev = prev;
90 loop {
91 let next = enter(inet, prev);
92 if next == ROOT {
94 return path.get(0).cloned().unwrap_or(ROOT); }
96 if slot(next) == 0 {
98 if slot(prev) == 0 {
100 inet.rules += 1;
101 rewrite(inet, addr(prev), addr(next));
102 prev = path.pop().unwrap();
103 continue;
104 } else {
106 return next;
107 }
108 }
109 path.push(prev);
111 prev = port(addr(next), 0);
112 }
113}
114
115pub fn normal(inet: &mut INet) {
117 let mut warp = vec![ROOT];
118 while let Some(prev) = warp.pop() {
119 let next = reduce(inet, prev);
120 if slot(next) == 0 {
121 warp.push(port(addr(next), 1));
122 warp.push(port(addr(next), 2));
123 }
124 }
125}
126
127pub fn rewrite(inet: &mut INet, x: Port, y: Port) {
129 if kind(inet, x) == kind(inet, y) {
130 let p0 = enter(inet, port(x, 1));
131 let p1 = enter(inet, port(y, 1));
132 link(inet, p0, p1);
133 let p0 = enter(inet, port(x, 2));
134 let p1 = enter(inet, port(y, 2));
135 link(inet, p0, p1);
136 inet.reuse.push(x);
137 inet.reuse.push(y);
138 } else {
139 let t = kind(inet, x);
140 let a = new_node(inet, t);
141 let t = kind(inet, y);
142 let b = new_node(inet, t);
143 let t = enter(inet, port(x, 1));
144 link(inet, port(b, 0), t);
145 let t = enter(inet, port(x, 2));
146 link(inet, port(y, 0), t);
147 let t = enter(inet, port(y, 1));
148 link(inet, port(a, 0), t);
149 let t = enter(inet, port(y, 2));
150 link(inet, port(x, 0), t);
151 link(inet, port(a, 1), port(b, 1));
152 link(inet, port(a, 2), port(y, 1));
153 link(inet, port(x, 1), port(b, 2));
154 link(inet, port(x, 2), port(y, 2));
155 }
156}