1use crate::circuit::Circuit;
14use crate::numeric::{Range, is_power_of_two_grid};
15use crate::wire::Wire;
16
17#[derive(Copy, Clone, Debug, PartialEq, Eq)]
19pub enum Policy {
20 Constant,
22 Input,
24 Event,
26 State,
28}
29
30#[derive(Copy, Clone, Debug)]
31pub struct CellSpec {
32 pub policy: Policy,
33 pub range: Range,
34 pub initial: f64,
35 pub exact_bit: bool,
36 pub grid: Option<f64>,
37}
38
39impl CellSpec {
40 fn new(policy: Policy, min: f64, max: f64, exact_bit: bool) -> CellSpec {
41 assert!(min <= max, "a cell's range is inverted: {min}..{max}");
42 CellSpec { policy, range: Range::new(min, max), initial: 0.0, exact_bit, grid: None }
43 }
44
45 pub fn initial(mut self, value: f64) -> CellSpec {
46 self.initial = value;
47 self
48 }
49
50 pub fn grid(mut self, step: f64) -> CellSpec {
52 assert!(is_power_of_two_grid(step), "a grid step must be a power of two");
53 self.grid = Some(step);
54 self
55 }
56}
57
58pub fn constant(value: f64, min: f64, max: f64) -> CellSpec {
59 CellSpec::new(Policy::Constant, min, max, false).initial(value)
60}
61pub fn input(min: f64, max: f64) -> CellSpec {
62 CellSpec::new(Policy::Input, min, max, false)
63}
64pub fn input_bit() -> CellSpec {
65 CellSpec::new(Policy::Input, 0.0, 1.0, true)
66}
67pub fn event() -> CellSpec {
68 CellSpec::new(Policy::Event, 0.0, 1.0, true)
69}
70pub fn state(min: f64, max: f64) -> CellSpec {
71 CellSpec::new(Policy::State, min, max, false)
72}
73pub fn state_bit() -> CellSpec {
74 CellSpec::new(Policy::State, 0.0, 1.0, true)
75}
76
77#[derive(Clone, Debug)]
78struct DeclaredCell {
79 name: String,
80 spec: CellSpec,
81 next: Option<Wire>,
82}
83
84#[derive(Clone, Debug, Default)]
85pub struct SourceTable {
86 cells: Vec<DeclaredCell>,
87 circuit_created: bool,
88}
89
90impl SourceTable {
91 pub fn new() -> SourceTable {
92 SourceTable::default()
93 }
94
95 pub fn declare(&mut self, name: impl Into<String>, spec: CellSpec) -> Wire {
97 assert!(!self.circuit_created, "declare every cell before create_circuit");
98 let name = name.into();
99 assert!(self.cells.iter().all(|cell| cell.name != name), "cell {name} is declared twice");
100 self.cells.push(DeclaredCell { name, spec, next: None });
101 Wire::from_index(self.cells.len() - 1)
102 }
103
104 pub fn len(&self) -> usize {
105 self.cells.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
109 self.cells.is_empty()
110 }
111
112 pub fn create_circuit(&mut self) -> Circuit {
114 self.circuit_created = true;
115 let mut circuit = Circuit::new(self.cells.len());
116 for (index, cell) in self.cells.iter().enumerate() {
117 let wire = Wire::from_index(index);
118 if cell.spec.exact_bit {
119 circuit.assume_bit(wire);
120 circuit.assume_grid(wire, 1.0);
121 } else {
122 circuit.assume_range(wire, cell.spec.range.min, cell.spec.range.max);
123 }
124 if let Some(grid) = cell.spec.grid {
125 circuit.assume_grid(wire, grid);
126 }
127 }
128 circuit
129 }
130
131 pub fn next(&mut self, cell: Wire, value: Wire) {
133 let declared = &mut self.cells[cell.index()];
134 assert_eq!(declared.spec.policy, Policy::State, "{} is not a state cell", declared.name);
135 assert!(declared.next.is_none(), "{} already has a next value", declared.name);
136 declared.next = Some(value);
137 }
138
139 pub fn finish(&self) {
141 for cell in &self.cells {
142 if cell.spec.policy == Policy::State {
143 assert!(cell.next.is_some(), "state cell {} has no next value", cell.name);
144 }
145 }
146 }
147
148 pub fn next_wires(&self) -> Vec<Wire> {
150 self.cells.iter().filter_map(|cell| cell.next).collect()
151 }
152
153 pub fn initial(&self) -> Vec<f32> {
154 self.cells.iter().map(|cell| cell.spec.initial as f32).collect()
155 }
156
157 pub fn validate(&self, source: &[f32]) -> Result<(), String> {
159 if source.len() != self.cells.len() {
160 return Err(format!("source table has {} cells, expected {}", source.len(), self.cells.len()));
161 }
162 for (cell, &value) in self.cells.iter().zip(source) {
163 let value = value as f64;
164 let range = cell.spec.range;
165 if !(value >= range.min && value <= range.max) {
166 return Err(format!("{} is {value}, outside {}..{}", cell.name, range.min, range.max));
167 }
168 if cell.spec.exact_bit && value != 0.0 && value != 1.0 {
169 return Err(format!("{} must be exactly 0 or 1, got {value}", cell.name));
170 }
171 if let Some(grid) = cell.spec.grid
172 && (value / grid).fract() != 0.0
173 {
174 return Err(format!("{} must be a multiple of {grid}, got {value}", cell.name));
175 }
176 }
177 Ok(())
178 }
179
180 pub fn advance(&self, source: &[f32], values: &[f32]) -> Vec<f32> {
183 self.cells
184 .iter()
185 .zip(source)
186 .map(|(cell, &value)| match (cell.spec.policy, cell.next) {
187 (Policy::State, Some(next)) => values[next.index()],
188 (Policy::Event, _) => 0.0,
189 _ => value,
190 })
191 .collect()
192 }
193}