1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8#[derive(Clone, Debug)]
10pub enum PcfValue {
11 Num(u64),
13 BoolVal(bool),
15 Bottom,
17 Fun(String),
19}
20#[derive(Clone, Debug, PartialEq, Eq)]
22pub enum GradualType {
23 Unknown,
25 Base(String),
27 Arrow(Box<GradualType>, Box<GradualType>),
29 Prod(Box<GradualType>, Box<GradualType>),
31}
32pub struct CubicalPath<A: Clone> {
36 pub dim: usize,
38 path_fn: Box<dyn Fn(Vec<bool>) -> A>,
40}
41impl<A: Clone + 'static> CubicalPath<A> {
42 pub fn constant(value: A) -> Self {
44 let v = value.clone();
45 Self {
46 dim: 0,
47 path_fn: Box::new(move |_face| v.clone()),
48 }
49 }
50 pub fn from_fn(f: impl Fn(bool) -> A + 'static) -> Self {
52 Self {
53 dim: 1,
54 path_fn: Box::new(move |face| {
55 let i = face.first().copied().unwrap_or(false);
56 f(i)
57 }),
58 }
59 }
60 pub fn at(&self, face: Vec<bool>) -> A {
62 (self.path_fn)(face)
63 }
64 pub fn left(&self) -> A {
66 self.at(vec![false])
67 }
68 pub fn right(&self) -> A {
70 self.at(vec![true])
71 }
72 pub fn face0(&self) -> A {
74 let mut face = vec![false; self.dim.max(1)];
75 face[0] = false;
76 self.at(face)
77 }
78 pub fn face1(&self) -> A {
80 let mut face = vec![false; self.dim.max(1)];
81 face[0] = true;
82 self.at(face)
83 }
84 pub fn meet(&self, j: bool) -> A {
86 self.at(vec![j])
87 }
88 pub fn join(&self, j: bool) -> A {
90 self.at(vec![!j])
91 }
92 pub fn reverse(self) -> CubicalPath<A>
94 where
95 A: 'static,
96 {
97 let f = self.path_fn;
98 CubicalPath {
99 dim: self.dim,
100 path_fn: Box::new(move |mut face| {
101 for b in face.iter_mut() {
102 *b = !*b;
103 }
104 f(face)
105 }),
106 }
107 }
108}
109pub struct LogicalRelation {
112 pub ty: SimpleType,
114 pub(super) pred: Box<dyn Fn(&str, &str) -> bool>,
116}
117impl LogicalRelation {
118 pub fn base(name: impl Into<String>, pred: impl Fn(&str, &str) -> bool + 'static) -> Self {
120 Self {
121 ty: SimpleType::Base(name.into()),
122 pred: Box::new(pred),
123 }
124 }
125 pub fn arrow(dom: LogicalRelation, cod: LogicalRelation) -> Self {
128 let dom_ty = dom.ty.clone();
129 let cod_ty = cod.ty.clone();
130 let dom_pred = dom.pred;
131 let cod_pred = cod.pred;
132 Self {
133 ty: SimpleType::Arrow(Box::new(dom_ty), Box::new(cod_ty)),
134 pred: Box::new(move |f, g| {
135 if f == g {
136 return true;
137 }
138 let fa = format!("{f}(x)");
139 let gb = format!("{g}(x)");
140 dom_pred("x", "x") && cod_pred(&fa, &gb)
141 }),
142 }
143 }
144 pub fn relates(&self, a: &str, b: &str) -> bool {
146 (self.pred)(a, b)
147 }
148 pub fn self_related(&self, term: &str) -> bool {
150 self.relates(term, term)
151 }
152}
153#[derive(Clone, Debug)]
155pub enum ConsistencyEvidence {
156 Refl,
158 LeftDyn,
160 RightDyn,
162 ArrowCons(Box<ConsistencyEvidence>, Box<ConsistencyEvidence>),
164 ProdCons(Box<ConsistencyEvidence>, Box<ConsistencyEvidence>),
166}
167#[derive(Clone, Debug)]
169pub struct RelationPair<A, B> {
170 pub left: A,
172 pub right: B,
174}
175pub struct GradualTyper;
177impl GradualTyper {
178 pub fn consistent(a: &GradualType, b: &GradualType) -> Option<ConsistencyEvidence> {
180 match (a, b) {
181 (GradualType::Unknown, _) => Some(ConsistencyEvidence::LeftDyn),
182 (_, GradualType::Unknown) => Some(ConsistencyEvidence::RightDyn),
183 (GradualType::Base(x), GradualType::Base(y)) if x == y => {
184 Some(ConsistencyEvidence::Refl)
185 }
186 (GradualType::Arrow(a1, b1), GradualType::Arrow(a2, b2)) => {
187 let ev_a = Self::consistent(a1, a2)?;
188 let ev_b = Self::consistent(b1, b2)?;
189 Some(ConsistencyEvidence::ArrowCons(
190 Box::new(ev_a),
191 Box::new(ev_b),
192 ))
193 }
194 (GradualType::Prod(a1, b1), GradualType::Prod(a2, b2)) => {
195 let ev_a = Self::consistent(a1, a2)?;
196 let ev_b = Self::consistent(b1, b2)?;
197 Some(ConsistencyEvidence::ProdCons(
198 Box::new(ev_a),
199 Box::new(ev_b),
200 ))
201 }
202 _ => None,
203 }
204 }
205 pub fn unknown_is_consistent_with_any(b: &GradualType) -> bool {
207 Self::consistent(&GradualType::Unknown, b).is_some()
208 }
209 pub fn is_symmetric(a: &GradualType, b: &GradualType) -> bool {
211 Self::consistent(a, b).is_some() == Self::consistent(b, a).is_some()
212 }
213 pub fn precision(a: &GradualType, b: &GradualType) -> bool {
216 match (a, b) {
217 (_, GradualType::Unknown) => true,
218 (GradualType::Unknown, _) => false,
219 (GradualType::Base(x), GradualType::Base(y)) => x == y,
220 (GradualType::Arrow(a1, b1), GradualType::Arrow(a2, b2)) => {
221 Self::precision(a1, a2) && Self::precision(b1, b2)
222 }
223 (GradualType::Prod(a1, b1), GradualType::Prod(a2, b2)) => {
224 Self::precision(a1, a2) && Self::precision(b1, b2)
225 }
226 _ => false,
227 }
228 }
229}
230#[derive(Clone, Debug, PartialEq, Eq)]
232pub enum SimpleType {
233 Base(String),
235 Arrow(Box<SimpleType>, Box<SimpleType>),
237 Product(Box<SimpleType>, Box<SimpleType>),
239 Forall(String, Box<SimpleType>),
241}
242pub struct FreeTheoremDeriver {
248 pub type_sig: String,
250 pub theorem: String,
252}
253impl FreeTheoremDeriver {
254 pub fn list_endomorphism() -> Self {
256 Self {
257 type_sig: "forall alpha. List alpha -> List alpha".into(),
258 theorem: "forall (A B : Type) (h : A -> B) (f : forall alpha, List alpha -> List alpha) (xs : List A), map h (f A xs) = f B (map h xs)"
259 .into(),
260 }
261 }
262 pub fn poly_identity() -> Self {
264 Self {
265 type_sig: "forall alpha. alpha -> alpha".into(),
266 theorem: "forall (A : Type) (f : forall alpha, alpha -> alpha) (x : A), f A x = x"
267 .into(),
268 }
269 }
270 pub fn poly_map() -> Self {
272 Self {
273 type_sig: "forall alpha beta. (alpha -> beta) -> List alpha -> List beta"
274 .into(),
275 theorem: "forall (A B C D : Type) (h : A -> B) (k : C -> D) (f : forall alpha beta, (alpha -> beta) -> List alpha -> List beta) (g : A -> C) (xs : List A), map k (f A C g xs) = f B D (k . g . h^-1) (map h xs)"
276 .into(),
277 }
278 }
279 pub fn verify_identity_theorem(xs: Vec<i32>) -> bool {
283 let mapped: Vec<i32> = xs.iter().map(|&x| x).collect();
284 mapped == xs
285 }
286 pub fn verify_reverse_naturality<A: Clone, B: Clone>(f: impl Fn(A) -> B, xs: Vec<A>) -> bool {
288 let mapped_then_rev: Vec<B> = xs
289 .iter()
290 .map(|x| f(x.clone()))
291 .collect::<Vec<_>>()
292 .into_iter()
293 .rev()
294 .collect();
295 let rev_then_mapped: Vec<B> = xs.into_iter().rev().map(f).collect();
296 mapped_then_rev.len() == rev_then_mapped.len()
297 && mapped_then_rev
298 .iter()
299 .zip(rev_then_mapped.iter())
300 .all(|_| true)
301 }
302}
303#[derive(Clone, Debug, PartialEq, Eq)]
305pub enum PcfType {
306 Nat,
308 Bool,
310 Fun(Box<PcfType>, Box<PcfType>),
312}
313pub struct RealizabilityModel {
318 pub ty: PcfType,
320}
321impl RealizabilityModel {
322 pub fn new(ty: PcfType) -> Self {
324 Self { ty }
325 }
326 pub fn is_realizer(&self, val: &PcfValue) -> bool {
328 match (&self.ty, val) {
329 (PcfType::Nat, PcfValue::Num(_)) => true,
330 (PcfType::Bool, PcfValue::BoolVal(_)) => true,
331 (PcfType::Fun(_, _), PcfValue::Fun(_)) => true,
332 (_, PcfValue::Bottom) => true,
333 _ => false,
334 }
335 }
336 pub fn per_equiv(&self, v1: &PcfValue, v2: &PcfValue) -> bool {
340 if !self.is_realizer(v1) || !self.is_realizer(v2) {
341 return false;
342 }
343 match (v1, v2) {
344 (PcfValue::Num(a), PcfValue::Num(b)) => a == b,
345 (PcfValue::BoolVal(a), PcfValue::BoolVal(b)) => a == b,
346 (PcfValue::Bottom, PcfValue::Bottom) => false,
347 (PcfValue::Fun(f), PcfValue::Fun(g)) => f == g,
348 _ => false,
349 }
350 }
351 pub fn domain(&self) -> impl Fn(&PcfValue) -> bool + '_ {
353 move |v| self.per_equiv(v, v)
354 }
355}
356#[derive(Clone, Debug)]
360pub struct CubicalPoint<A: Clone> {
361 pub dim: usize,
363 pub value: A,
365 pub face: Vec<bool>,
367}