oxilean_std/sigma/
types.rs1use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::functions::*;
8use std::collections::BTreeMap;
9
10#[allow(dead_code)]
14#[derive(Debug, Clone)]
15pub struct DependentTelescope {
16 fields: Vec<(String, String)>,
17}
18#[allow(dead_code)]
19impl DependentTelescope {
20 pub fn new() -> Self {
22 Self { fields: Vec::new() }
23 }
24 pub fn extend(&self, name: impl Into<String>, ty_desc: impl Into<String>) -> Self {
26 let mut fields = self.fields.clone();
27 fields.push((name.into(), ty_desc.into()));
28 Self { fields }
29 }
30 pub fn depth(&self) -> usize {
32 self.fields.len()
33 }
34 pub fn field_names(&self) -> Vec<&str> {
36 self.fields.iter().map(|(n, _)| n.as_str()).collect()
37 }
38 pub fn has_field(&self, name: &str) -> bool {
40 self.fields.iter().any(|(n, _)| n == name)
41 }
42 pub fn field_type(&self, name: &str) -> Option<&str> {
44 self.fields
45 .iter()
46 .find(|(n, _)| n == name)
47 .map(|(_, t)| t.as_str())
48 }
49 pub fn truncate(&self, depth: usize) -> Self {
51 Self {
52 fields: self.fields[..self.fields.len().min(depth)].to_vec(),
53 }
54 }
55}
56#[allow(dead_code)]
60#[derive(Debug, Clone)]
61pub struct RefinementValue<T: Clone> {
62 value: T,
63 predicate_name: String,
64 predicate_holds: bool,
65}
66#[allow(dead_code)]
67impl<T: Clone> RefinementValue<T> {
68 pub fn new(
70 value: T,
71 predicate_name: impl Into<String>,
72 predicate: impl Fn(&T) -> bool,
73 ) -> Self {
74 let holds = predicate(&value);
75 Self {
76 value,
77 predicate_name: predicate_name.into(),
78 predicate_holds: holds,
79 }
80 }
81 pub fn val(&self) -> &T {
83 &self.value
84 }
85 pub fn is_valid(&self) -> bool {
87 self.predicate_holds
88 }
89 pub fn predicate_name(&self) -> &str {
91 &self.predicate_name
92 }
93 pub fn coerce(
96 &self,
97 new_name: impl Into<String>,
98 implication: impl Fn(&T) -> bool,
99 ) -> RefinementValue<T> {
100 RefinementValue::new(self.value.clone(), new_name, implication)
101 }
102}
103#[allow(dead_code)]
106pub struct ExistentialPack<Interface> {
107 value: Box<dyn std::any::Any + Send + Sync>,
108 interface: Interface,
109 type_name: &'static str,
110}
111#[allow(dead_code)]
112impl<Interface: Clone> ExistentialPack<Interface> {
113 pub fn pack<T: std::any::Any + Send + Sync>(
115 value: T,
116 interface: Interface,
117 type_name: &'static str,
118 ) -> Self {
119 Self {
120 value: Box::new(value),
121 interface,
122 type_name,
123 }
124 }
125 pub fn interface(&self) -> &Interface {
127 &self.interface
128 }
129 pub fn hidden_type_name(&self) -> &'static str {
131 self.type_name
132 }
133 pub fn unpack<T: std::any::Any + Clone>(&self) -> Option<T> {
135 self.value.downcast_ref::<T>().cloned()
136 }
137}
138#[allow(dead_code)]
141#[derive(Debug, Clone)]
142pub struct WNode<A: Clone, B: Clone + Ord> {
143 label: A,
144 children: std::collections::BTreeMap<B, WNode<A, B>>,
145}
146#[allow(dead_code)]
147impl<A: Clone, B: Clone + Ord> WNode<A, B> {
148 pub fn leaf(label: A) -> Self {
150 Self {
151 label,
152 children: std::collections::BTreeMap::new(),
153 }
154 }
155 pub fn node(label: A, children: std::collections::BTreeMap<B, WNode<A, B>>) -> Self {
157 Self { label, children }
158 }
159 pub fn label(&self) -> &A {
161 &self.label
162 }
163 pub fn arity(&self) -> usize {
165 self.children.len()
166 }
167 pub fn height(&self) -> usize {
169 if self.children.is_empty() {
170 0
171 } else {
172 1 + self
173 .children
174 .values()
175 .map(|c| c.height())
176 .max()
177 .unwrap_or(0)
178 }
179 }
180 pub fn size(&self) -> usize {
182 1 + self.children.values().map(|c| c.size()).sum::<usize>()
183 }
184 pub fn map_labels<C: Clone>(&self, f: &impl Fn(&A) -> C) -> WNode<C, B> {
186 WNode {
187 label: f(&self.label),
188 children: self
189 .children
190 .iter()
191 .map(|(k, v)| (k.clone(), v.map_labels(f)))
192 .collect(),
193 }
194 }
195 pub fn fold<R: Clone>(&self, f: &impl Fn(&A, Vec<R>) -> R) -> R {
197 let child_results: Vec<R> = self.children.values().map(|c| c.fold(f)).collect();
198 f(&self.label, child_results)
199 }
200}
201#[allow(dead_code)]
204#[derive(Debug, Clone)]
205pub struct RowRecord {
206 fields: std::collections::BTreeMap<String, String>,
207}
208#[allow(dead_code)]
209impl RowRecord {
210 pub fn empty() -> Self {
212 Self {
213 fields: std::collections::BTreeMap::new(),
214 }
215 }
216 pub fn with(mut self, label: impl Into<String>, ty: impl Into<String>) -> Self {
218 self.fields.insert(label.into(), ty.into());
219 self
220 }
221 pub fn is_width_subtype_of(&self, other: &RowRecord) -> bool {
223 other
224 .fields
225 .keys()
226 .all(|k| self.fields.contains_key(k.as_str()))
227 }
228 pub fn is_depth_subtype_of(&self, other: &RowRecord) -> bool {
231 other.fields.iter().all(|(k, v)| {
232 self.fields
233 .get(k.as_str())
234 .map(|tv| tv == v)
235 .unwrap_or(false)
236 })
237 }
238 pub fn width(&self) -> usize {
240 self.fields.len()
241 }
242 pub fn restrict(&self, labels: &[&str]) -> Self {
244 Self {
245 fields: labels
246 .iter()
247 .filter_map(|l| self.fields.get(*l).map(|v| ((*l).to_string(), v.clone())))
248 .collect(),
249 }
250 }
251 pub fn merge(&self, other: &RowRecord) -> Self {
253 let mut fields = self.fields.clone();
254 for (k, v) in &other.fields {
255 fields.insert(k.clone(), v.clone());
256 }
257 Self { fields }
258 }
259}