1pub use crate::{
2 anon::Anon,
3 defs,
4 embed_error::EmbedError,
5 literal::{
6 LitType,
7 Literal,
8 },
9 meta::Meta,
10 name::Name,
11 parse,
12 position::Pos,
13 prim::Op,
14 uses::Uses,
15};
16
17use sp_cid::Cid;
18
19use sp_std::{
20 borrow::ToOwned,
21 boxed::Box,
22 fmt,
23 rc::Rc,
24};
25
26use alloc::string::{
27 String,
28 ToString,
29};
30
31#[derive(Clone)]
33pub enum Term {
34 Var(Pos, Name, u64),
36 Lam(Pos, Name, Box<Term>),
38 App(Pos, Box<(Term, Term)>),
40 All(Pos, Uses, Name, Box<(Term, Term)>),
42 Slf(Pos, Name, Box<Term>),
44 Dat(Pos, Box<Term>),
46 Cse(Pos, Box<Term>),
48 Ref(Pos, Name, Cid, Cid),
50 Let(Pos, bool, Uses, Name, Box<(Term, Term, Term)>),
52 Typ(Pos),
54 Ann(Pos, Box<(Term, Term)>),
56 Lit(Pos, Literal),
58 LTy(Pos, LitType),
60 Opr(Pos, Op),
62 Rec(Pos),
64}
65
66impl fmt::Debug for Term {
67 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
68 match self {
69 Self::Var(_, n, i) => fmt.debug_tuple("Var").field(&n).field(i).finish(),
70 Self::Lam(_, n, b) => fmt.debug_tuple("Lam").field(&n).field(&b).finish(),
71 Self::App(_, t) => fmt.debug_tuple("App").field(&t).finish(),
72 Self::All(_, u, n, t) => {
73 fmt.debug_tuple("All").field(&u).field(&n).field(&t).finish()
74 }
75 Self::Slf(_, n, b) => fmt.debug_tuple("Slf").field(&n).field(&b).finish(),
76 Self::Dat(_, b) => fmt.debug_tuple("Dat").field(&b).finish(),
77 Self::Cse(_, b) => fmt.debug_tuple("Cse").field(&b).finish(),
78 Self::Ref(_, n, d, a) => {
79 fmt.debug_tuple("Ref").field(&n).field(&d).field(&a).finish()
80 }
81 Self::Let(_, r, u, n, t) => {
82 fmt.debug_tuple("Let").field(r).field(&u).field(&n).field(&t).finish()
83 }
84 Self::Typ(_) => write!(fmt, "Typ(..)"),
85 Self::Ann(_, t) => fmt.debug_tuple("Ann").field(&t).finish(),
86 Self::Lit(_, a) => fmt.debug_tuple("Lit").field(&a).finish(),
87 Self::LTy(_, a) => fmt.debug_tuple("LTy").field(&a).finish(),
88 Self::Opr(_, a) => fmt.debug_tuple("Opr").field(&a).finish(),
89 Self::Rec(_) => write!(fmt, "Rec(..)"),
90 }
91 }
92}
93
94impl PartialEq for Term {
95 fn eq(&self, other: &Self) -> bool {
96 match (self, other) {
97 (Self::Var(_, na, ia), Self::Var(_, nb, ib)) => na == nb && ia == ib,
98 (Self::Lam(_, na, ba), Self::Lam(_, nb, bb)) => na == nb && ba == bb,
99 (Self::App(_, ta), Self::App(_, tb)) => ta.0 == tb.0 && ta.1 == tb.1,
100 (Self::All(_, ua, na, ta), Self::All(_, ub, nb, tb)) => {
101 ua == ub && na == nb && ta.0 == tb.0 && ta.1 == tb.1
102 }
103 (Self::Slf(_, na, ba), Self::Slf(_, nb, bb)) => na == nb && ba == bb,
104 (Self::Dat(_, ba), Self::Dat(_, bb)) => ba == bb,
105 (Self::Cse(_, ba), Self::Cse(_, bb)) => ba == bb,
106 (Self::Ref(_, na, da, aa), Self::Ref(_, nb, db, ab)) => {
107 na == nb && da == db && aa == ab
108 }
109 (Self::Let(_, ra, ua, na, ta), Self::Let(_, rb, ub, nb, tb)) => {
110 ra == rb
111 && ua == ub
112 && na == nb
113 && ta.0 == tb.0
114 && ta.1 == tb.1
115 && ta.2 == tb.2
116 }
117 (Self::Typ(_), Self::Typ(_)) => true,
118 (Self::Rec(_), Self::Rec(_)) => true,
119 (Self::Ann(_, ta), Self::Ann(_, tb)) => ta.0 == tb.0 && ta.1 == tb.1,
120 (Self::Lit(_, a), Self::Lit(_, b)) => a == b,
121 (Self::LTy(_, a), Self::LTy(_, b)) => a == b,
122 (Self::Opr(_, a), Self::Opr(_, b)) => a == b,
123 _ => false,
124 }
125 }
126}
127
128impl Term {
129 pub fn pos(&self) -> Pos {
131 match self {
132 Term::Var(pos, ..) => *pos,
133 Term::Ref(pos, ..) => *pos,
134 Term::Lam(pos, ..) => *pos,
135 Term::App(pos, _) => *pos,
136 Term::Ann(pos, _) => *pos,
137 Term::All(pos, ..) => *pos,
138 Term::Slf(pos, ..) => *pos,
139 Term::Dat(pos, _) => *pos,
140 Term::Cse(pos, _) => *pos,
141 Term::Let(pos, ..) => *pos,
142 Term::Typ(pos) => *pos,
143 Term::LTy(pos, _) => *pos,
144 Term::Lit(pos, _) => *pos,
145 Term::Opr(pos, _) => *pos,
146 Term::Rec(pos) => *pos,
147 }
148 }
149
150 pub fn shift(self, inc: i64, dep: Option<u64>) -> Self {
152 match self {
153 Self::Var(pos, nam, idx) => match dep {
154 Some(dep) if idx < dep => Self::Var(pos, nam, idx),
155 _ => Self::Var(pos, nam, ((idx as i64) + inc) as u64),
156 },
157 Self::Lam(pos, nam, bod) => {
158 Self::Lam(pos, nam, Box::new((*bod).shift(inc, dep.map(|x| x + 1))))
159 }
160 Self::Slf(pos, nam, bod) => {
161 Self::Slf(pos, nam, Box::new((*bod).shift(inc, dep.map(|x| x + 1))))
162 }
163 Self::Cse(pos, bod) => Self::Cse(pos, Box::new((*bod).shift(inc, dep))),
164 Self::Dat(pos, bod) => Self::Dat(pos, Box::new((*bod).shift(inc, dep))),
165 Self::App(pos, fun_arg) => {
166 let (fun, arg) = *fun_arg;
167 Self::App(pos, Box::new((fun.shift(inc, dep), arg.shift(inc, dep))))
168 }
169 Self::Ann(pos, typ_exp) => {
170 let (typ, exp) = *typ_exp;
171 Self::Ann(pos, Box::new((typ.shift(inc, dep), exp.shift(inc, dep))))
172 }
173 Self::All(pos, uses, nam, dom_img) => {
174 let (dom, img) = *dom_img;
175 Self::All(
176 pos,
177 uses,
178 nam,
179 Box::new((dom.shift(inc, dep), img.shift(inc, dep.map(|x| x + 1)))),
180 )
181 }
182 Self::Let(pos, rec, uses, nam, typ_exp_bod) => {
183 let (typ, exp, bod) = *typ_exp_bod;
184 Self::Let(
185 pos,
186 rec,
187 uses,
188 nam,
189 Box::new((
190 typ.shift(inc, dep),
191 exp.shift(inc, if rec { dep.map(|x| x + 1) } else { dep }),
192 bod.shift(inc, dep.map(|x| x + 1)),
193 )),
194 )
195 }
196 x => x,
197 }
198 }
199
200 pub fn un_rec(self, trm: Rc<Term>) -> Self {
202 match self {
203 Self::Rec(_) => trm.as_ref().clone(),
204 Self::Lam(pos, nam, bod) => {
205 Self::Lam(pos, nam, Box::new((*bod).un_rec(trm)))
206 }
207 Self::Slf(pos, nam, bod) => {
208 Self::Slf(pos, nam, Box::new((*bod).un_rec(trm)))
209 }
210 Self::Cse(pos, bod) => Self::Cse(pos, Box::new((*bod).un_rec(trm))),
211 Self::Dat(pos, bod) => Self::Dat(pos, Box::new((*bod).un_rec(trm))),
212 Self::App(pos, fun_arg) => {
213 let (fun, arg) = *fun_arg;
214 Self::App(pos, Box::new((fun.un_rec(trm.clone()), arg.un_rec(trm))))
215 }
216 Self::Ann(pos, typ_exp) => {
217 let (typ, exp) = *typ_exp;
218 Self::Ann(pos, Box::new((typ.un_rec(trm.clone()), exp.un_rec(trm))))
219 }
220 Self::All(pos, uses, nam, dom_img) => {
221 let (dom, img) = *dom_img;
222 Self::All(
223 pos,
224 uses,
225 nam,
226 Box::new((dom.un_rec(trm.clone()), img.un_rec(trm))),
227 )
228 }
229 Self::Let(pos, rec, uses, nam, typ_exp_bod) => {
230 let (typ, exp, bod) = *typ_exp_bod;
231 Self::Let(
232 pos,
233 rec,
234 uses,
235 nam,
236 Box::new((
237 typ.un_rec(trm.clone()),
238 exp.un_rec(trm.clone()),
239 bod.un_rec(trm),
240 )),
241 )
242 }
243 x => x,
244 }
245 }
246
247 pub fn embed(&self) -> (Anon, Meta) {
250 match self {
251 Self::Var(pos, name, idx) => {
252 (Anon::Var(*idx), Meta::Var(*pos, name.clone()))
253 }
254 Self::Ref(pos, name, def, ast) => {
255 (Anon::Ref(*ast), Meta::Ref(*pos, name.clone(), *def))
256 }
257 Self::Lit(pos, lit) => (Anon::Lit(lit.clone()), Meta::Lit(*pos)),
258 Self::LTy(pos, lty) => (Anon::LTy(*lty), Meta::LTy(*pos)),
259 Self::Opr(pos, opr) => (Anon::Opr(opr.clone()), Meta::Opr(*pos)),
260 Self::Rec(pos) => (Anon::Rec, Meta::Rec(*pos)),
261 Self::Typ(pos) => (Anon::Typ, Meta::Typ(*pos)),
262 Self::Lam(pos, name, body) => {
263 let (anon, meta) = (*body).embed();
264 (
265 Anon::Lam(Box::new(anon)),
266 Meta::Lam(*pos, name.clone(), Box::new(meta)),
267 )
268 }
269 Self::Slf(pos, name, body) => {
270 let (anon, meta) = (*body).embed();
271 (
272 Anon::Slf(Box::new(anon)),
273 Meta::Slf(*pos, name.clone(), Box::new(meta)),
274 )
275 }
276 Self::App(pos, terms) => {
277 let (fun_anon, fun_meta) = terms.0.embed();
278 let (arg_anon, arg_meta) = terms.1.embed();
279 (
280 Anon::App(Box::new((fun_anon, arg_anon))),
281 Meta::App(*pos, Box::new((fun_meta, arg_meta))),
282 )
283 }
284 Self::Ann(pos, terms) => {
285 let (typ_anon, typ_meta) = terms.0.embed();
286 let (exp_anon, exp_meta) = terms.1.embed();
287 (
288 Anon::Ann(Box::new((typ_anon, exp_anon))),
289 Meta::Ann(*pos, Box::new((typ_meta, exp_meta))),
290 )
291 }
292 Self::Dat(pos, body) => {
293 let (anon, meta) = (*body).embed();
294 (Anon::Dat(Box::new(anon)), Meta::Dat(*pos, Box::new(meta)))
295 }
296 Self::Cse(pos, body) => {
297 let (anon, meta) = (*body).embed();
298 (Anon::Cse(Box::new(anon)), Meta::Cse(*pos, Box::new(meta)))
299 }
300 Self::All(pos, uses, name, terms) => {
301 let (typ_anon, typ_meta) = terms.0.embed();
302 let (bod_anon, bod_meta) = terms.1.embed();
303 (
304 Anon::All(*uses, Box::new((typ_anon, bod_anon))),
305 Meta::All(*pos, name.clone(), Box::new((typ_meta, bod_meta))),
306 )
307 }
308 Self::Let(pos, rec, uses, name, terms) => {
309 let (typ_anon, typ_meta) = terms.0.embed();
310 let (exp_anon, exp_meta) = terms.1.embed();
311 let (bod_anon, bod_meta) = terms.2.embed();
312 (
313 Anon::Let(*rec, *uses, Box::new((typ_anon, exp_anon, bod_anon))),
314 Meta::Let(
315 *pos,
316 name.clone(),
317 Box::new((typ_meta, exp_meta, bod_meta)),
318 ),
319 )
320 }
321 }
322 }
323
324 pub fn unembed(anon: &Anon, meta: &Meta) -> Result<Self, EmbedError> {
326 match (anon, meta) {
327 (Anon::Var(idx), Meta::Var(pos, nam)) => {
328 Ok(Self::Var(*pos, nam.clone(), *idx))
329 }
330 (Anon::Ref(ast), Meta::Ref(pos, nam, def)) => {
331 Ok(Self::Ref(*pos, nam.clone(), *def, *ast))
332 }
333 (Anon::Lit(lit), Meta::Lit(pos)) => Ok(Self::Lit(*pos, lit.clone())),
334 (Anon::LTy(lty), Meta::LTy(pos)) => Ok(Self::LTy(*pos, *lty)),
335 (Anon::Opr(opr), Meta::Opr(pos)) => Ok(Self::Opr(*pos, opr.clone())),
336 (Anon::Typ, Meta::Typ(pos)) => Ok(Self::Typ(*pos)),
337 (Anon::Rec, Meta::Rec(pos)) => Ok(Self::Rec(*pos)),
338 (Anon::Lam(anon_bod), Meta::Lam(pos, nam, meta_bod)) => {
339 let bod = Term::unembed(anon_bod, meta_bod)?;
340 Ok(Self::Lam(*pos, nam.clone(), Box::new(bod)))
341 }
342 (Anon::Slf(anon_bod), Meta::Slf(pos, nam, meta_bod)) => {
343 let bod = Term::unembed(anon_bod, meta_bod)?;
344 Ok(Self::Slf(*pos, nam.clone(), Box::new(bod)))
345 }
346 (Anon::Dat(anon_bod), Meta::Dat(pos, meta_bod)) => {
347 let bod = Term::unembed(anon_bod, meta_bod)?;
348 Ok(Self::Dat(*pos, Box::new(bod)))
349 }
350 (Anon::Cse(anon_bod), Meta::Cse(pos, meta_bod)) => {
351 let bod = Term::unembed(anon_bod, meta_bod)?;
352 Ok(Self::Cse(*pos, Box::new(bod)))
353 }
354 (Anon::App(anon), Meta::App(pos, meta)) => {
355 let (fun_anon, arg_anon) = anon.as_ref();
356 let (fun_meta, arg_meta) = meta.as_ref();
357 let fun = Term::unembed(fun_anon, fun_meta)?;
358 let arg = Term::unembed(arg_anon, arg_meta)?;
359 Ok(Self::App(*pos, Box::new((fun, arg))))
360 }
361 (Anon::Ann(anon), Meta::Ann(pos, meta)) => {
362 let (typ_anon, exp_anon) = anon.as_ref();
363 let (typ_meta, exp_meta) = meta.as_ref();
364 let typ = Term::unembed(typ_anon, typ_meta)?;
365 let exp = Term::unembed(exp_anon, exp_meta)?;
366 Ok(Self::Ann(*pos, Box::new((typ, exp))))
367 }
368 (Anon::All(uses, anon), Meta::All(pos, name, meta)) => {
369 let (dom_anon, img_anon) = anon.as_ref();
370 let (dom_meta, img_meta) = meta.as_ref();
371 let dom = Term::unembed(dom_anon, dom_meta)?;
372 let img = Term::unembed(img_anon, img_meta)?;
373 Ok(Self::All(*pos, *uses, name.clone(), Box::new((dom, img))))
374 }
375 (Anon::Let(rec, uses, anon), Meta::Let(pos, name, meta)) => {
376 let (typ_anon, exp_anon, bod_anon) = anon.as_ref();
377 let (typ_meta, exp_meta, bod_meta) = meta.as_ref();
378 let typ = Term::unembed(typ_anon, typ_meta)?;
379 let exp = Term::unembed(exp_anon, exp_meta)?;
380 let bod = Term::unembed(bod_anon, bod_meta)?;
381 Ok(Self::Let(
382 *pos,
383 *rec,
384 *uses,
385 name.clone(),
386 Box::new((typ, exp, bod)),
387 ))
388 }
389 (anon, meta) => Err(EmbedError::Term(anon.clone(), meta.clone())),
390 }
391 }
392
393 pub fn pretty(&self, rec: Option<&String>, ind: bool) -> String {
395 use Term::*;
396 const WILDCARD: &str = "_";
397
398 fn name(nam: &str) -> &str { if nam.is_empty() { WILDCARD } else { nam } }
399
400 fn uses(uses: &Uses) -> &str {
401 match uses {
402 Uses::None => "0 ",
403 Uses::Affi => "& ",
404 Uses::Once => "1 ",
405 Uses::Many => "",
406 }
407 }
408
409 fn is_atom(term: &Term) -> bool {
410 matches!(term, Var(..) | Ref(..) | Lit(..) | LTy(..) | Opr(..) | Typ(..))
411 }
412
413 fn lams(rec: Option<&String>, ind: bool, nam: &str, bod: &Term) -> String {
414 match bod {
415 Lam(_, nam2, bod2) => {
416 format!("{} {}", name(nam), lams(rec, ind, nam2, bod2))
417 }
418 _ => format!("{} => {}", nam, bod.pretty(rec, ind)),
419 }
420 }
421
422 fn alls(
423 rec: Option<&String>,
424 ind: bool,
425 use_: &Uses,
426 nam: &str,
427 typ: &Term,
428 bod: &Term,
429 ) -> String {
430 match bod {
431 All(_, bod_use, bod_nam, bod) => {
432 format!(
433 " ({}{}: {}){}",
434 uses(use_),
435 name(nam),
436 typ.pretty(rec, ind),
437 alls(rec, ind, bod_use, bod_nam, &bod.0, &bod.1)
438 )
439 }
440 _ => format!(
441 " ({}{}: {}) -> {}",
442 uses(use_),
443 name(nam),
444 typ.pretty(rec, ind),
445 bod.pretty(rec, ind)
446 ),
447 }
448 }
449
450 fn parens(rec: Option<&String>, ind: bool, term: &Term) -> String {
451 if is_atom(term) {
452 term.pretty(rec, ind)
453 }
454 else {
455 format!("({})", term.pretty(rec, ind))
456 }
457 }
458
459 fn apps(rec: Option<&String>, ind: bool, fun: &Term, arg: &Term) -> String {
460 match (fun, arg) {
461 (App(_, f), App(_, a)) => {
462 format!(
463 "{} ({})",
464 apps(rec, ind, &f.0, &f.1),
465 apps(rec, ind, &a.0, &a.1)
466 )
467 }
468 (App(_, f), arg) => {
469 format!("{} {}", apps(rec, ind, &f.0, &f.1), parens(rec, ind, arg))
470 }
471 (fun, App(_, a)) => {
472 format!("{} ({})", parens(rec, ind, fun), apps(rec, ind, &a.0, &a.1))
473 }
474 (fun, arg) => {
475 format!("{} {}", parens(rec, ind, fun), parens(rec, ind, arg))
476 }
477 }
478 }
479
480 match self {
481 Var(_, nam, index) => {
482 if ind {
483 format!("{}^{}", nam, index)
484 }
485 else {
486 nam.to_string()
487 }
488 }
489 Ref(_, nam, ..) => nam.to_string(),
490 Rec(_) => match rec {
491 Some(rec) => rec.to_owned(),
492 _ => "#^".to_string(),
493 },
494
495 Lam(_, nam, term) => format!("λ {}", lams(rec, ind, nam, term)),
496 App(_, terms) => apps(rec, ind, &terms.0, &terms.1),
497 Let(_, letrec, u, n, terms) => {
498 format!(
499 "let{} {}{}: {} = {}; {}",
500 if *letrec { "rec" } else { "" },
501 uses(u),
502 name(n),
503 terms.0.pretty(rec, ind),
504 terms.1.pretty(rec, ind),
505 terms.2.pretty(rec, ind),
506 )
507 }
508 Slf(_, nam, bod) => format!("@{} {}", name(nam), bod.pretty(rec, ind)),
509 All(_, us_, nam, terms) => {
510 format!("∀{}", alls(rec, ind, us_, nam, &terms.0, &terms.1))
511 }
512 Ann(_, terms) => {
513 format!(
514 "{} :: {}",
515 parens(rec, ind, &terms.1),
516 parens(rec, ind, &terms.0)
517 )
518 }
519 Dat(_, bod) => format!("data {}", bod.pretty(rec, ind)),
520 Cse(_, bod) => format!("case {}", bod.pretty(rec, ind)),
521 Typ(_) => "Type".to_string(),
522 Lit(_, lit) => format!("{}", lit),
523 LTy(_, lty) => format!("{}", lty),
524 Opr(_, opr) => format!("{}", opr),
525 }
526 }
527}
528
529impl fmt::Display for Term {
530 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
531 write!(f, "{}", self.pretty(None, false))
532 }
533}
534
535#[cfg(test)]
536pub mod tests {
537
538 use super::{
539 *,
540 };
541 use crate::{
542 defs::{
543 Def,
544 Defs,
545 },
546 yatima,
547 };
548 use quickcheck::{
549 Arbitrary,
550 Gen,
551 };
552 use sp_std::ops::Range;
553
554 use sp_im::Vector;
555 use sp_std::{
556 boxed::Box,
557 vec::Vec,
558 };
559
560 use crate::{
561 name::Name,
562 parse::term::is_valid_symbol_char,
563 };
564
565 pub fn arbitrary_name(g: &mut Gen) -> Name {
566 let s: String = Arbitrary::arbitrary(g);
567 let mut s: String = s
568 .chars()
569 .filter(|x| is_valid_symbol_char(*x) && char::is_ascii_alphabetic(x))
570 .collect();
571 s.truncate(1);
572 Name::from(format!("_{}", s))
573 }
574
575 pub fn test_defs() -> Defs {
576 let mut defs = Defs::new();
577 let (id, _) = Def::make(
578 Pos::None,
579 yatima!("∀ (A: Type) (x: A) -> A"),
580 yatima!("λ A x => x"),
581 );
582 let (fst, _) = Def::make(
583 Pos::None,
584 yatima!("∀ (A: Type) (x y: A) -> A"),
585 yatima!("λ A x y => x"),
586 );
587 let (snd, _) = Def::make(
588 Pos::None,
589 yatima!("∀ (A: Type) (x y: A) -> A"),
590 yatima!("λ A x y => y"),
591 );
592 defs.insert(Name::from("id"), id);
593 defs.insert(Name::from("fst"), fst);
594 defs.insert(Name::from("snd"), snd);
595 defs
596 }
597
598 fn arbitrary_ref(g: &mut Gen, defs: Defs, ctx: Vector<Name>) -> Tree {
599 let refs: Vec<(Name, Cid)> = defs
600 .names
601 .clone()
602 .into_iter()
603 .filter(|(n, _)| !ctx.contains(n))
604 .collect();
605 let len = refs.len();
606 if len == 0 {
607 return Tree::Typ;
608 };
609 let gen = gen_range(g, 0..(len - 1));
610 let (n, _) = refs[gen].clone();
611 let def = defs.get(&n).unwrap();
612 Tree::Ref(n.clone(), def.def_cid, def.ast_cid)
613 }
614
615 #[derive(Debug, Clone)]
616 pub enum Tree {
617 Var(Name, u64),
618 Typ,
619 Rec,
620 Ref(Name, Cid, Cid),
621 Opr(Op),
622 Lit(Literal),
623 LTy(LitType),
624 Lam(Name, usize),
625 Slf(Name, usize),
626 App(usize, usize),
627 Ann(usize, usize),
628 Cse(usize),
629 Dat(usize),
630 All(Uses, Name, usize, usize),
631 Let(bool, Uses, Name, usize, usize, usize),
632 }
633
634 impl Tree {
635 pub fn into_term(&self, arena: &Vec<Tree>) -> Term {
636 match self {
637 Self::Var(n, i) => Term::Var(Pos::None, n.clone(), *i),
638 Self::Rec => Term::Rec(Pos::None),
639 Self::Typ => Term::Typ(Pos::None),
640 Self::Ref(n, d, a) => Term::Ref(Pos::None, n.clone(), *d, *a),
641 Self::Opr(x) => Term::Opr(Pos::None, x.clone()),
642 Self::Lit(x) => Term::Lit(Pos::None, x.clone()),
643 Self::LTy(x) => Term::LTy(Pos::None, *x),
644 Self::Lam(n, bod) => {
645 let bod = arena[*bod].into_term(&arena);
646 Term::Lam(Pos::None, n.clone(), Box::new(bod))
647 }
648 Self::Slf(n, bod) => {
649 let bod = arena[*bod].into_term(&arena);
650 Term::Slf(Pos::None, n.clone(), Box::new(bod))
651 }
652 Self::Cse(bod) => {
653 let bod = arena[*bod].into_term(&arena);
654 Term::Cse(Pos::None, Box::new(bod))
655 }
656 Self::Dat(bod) => {
657 let bod = arena[*bod].into_term(&arena);
658 Term::Dat(Pos::None, Box::new(bod))
659 }
660 Self::App(fun, arg) => {
661 let fun = arena[*fun].into_term(&arena);
662 let arg = arena[*arg].into_term(&arena);
663 Term::App(Pos::None, Box::new((fun, arg)))
664 }
665 Self::Ann(typ, trm) => {
666 let typ = arena[*typ].into_term(&arena);
667 let trm = arena[*trm].into_term(&arena);
668 Term::Ann(Pos::None, Box::new((typ, trm)))
669 }
670 Self::All(uses, n, dom, img) => {
671 let dom = arena[*dom].into_term(&arena);
672 let img = arena[*img].into_term(&arena);
673 Term::All(Pos::None, *uses, n.clone(), Box::new((dom, img)))
674 }
675 Self::Let(rec, uses, n, typ, trm, bod) => {
676 let typ = arena[*typ].into_term(&arena);
677 let trm = arena[*trm].into_term(&arena);
678 let bod = arena[*bod].into_term(&arena);
679 Term::Let(
680 Pos::None,
681 *rec,
682 *uses,
683 n.clone(),
684 Box::new((typ, trm, bod)),
685 )
686 }
687 }
688 }
689 }
690
691 #[derive(Debug, Clone, Copy)]
692 pub enum Case {
693 VAR,
694 TYP,
695 REC,
696 REF,
697 LIT,
698 LTY,
699 OPR,
700 LAM,
701 APP,
702 ANN,
703 SLF,
704 CSE,
705 DAT,
706 ALL,
707 LET,
708 }
709
710 pub fn gen_range(g: &mut Gen, range: Range<usize>) -> usize {
711 let res: usize = Arbitrary::arbitrary(g);
712 (res % (range.end - range.start)) + range.start
713 }
714
715 pub fn next_case(g: &mut Gen, gens: &Vec<(usize, Case)>) -> Case {
716 let sum: usize = gens.iter().map(|x| x.0).sum();
717 let mut weight: usize = gen_range(g, 1..(sum + 1));
718 for gen in gens {
719 match weight.checked_sub(gen.0 + 1) {
720 None | Some(0) => {
721 return gen.1;
722 }
723 _ => {
724 weight -= gen.0;
725 }
726 }
727 }
728 panic!("Calculation error for weight = {}", weight);
729 }
730
731 pub fn arbitrary_term(
732 g: &mut Gen,
733 rec: bool,
734 defs: Defs,
735 ctx0: Vector<Name>,
736 ) -> Term {
737 let name = Name::from("_r");
738 let mut ctx1 = ctx0.clone();
739 ctx1.push_front(name.clone());
740 let mut ctxs: Vec<Vector<Name>> = vec![ctx0, ctx1];
741 let mut arena: Vec<Option<Tree>> = vec![Some(Tree::Lam(name, 1)), None];
742 let mut todo: Vec<usize> = vec![1];
743
744 while let Some(idx) = todo.pop() {
745 let ctx: Vector<Name> = ctxs[idx].clone();
746 let depth = ctx.len();
747 let gens: Vec<(usize, Case)> = vec![
748 (100, Case::VAR),
749 (100, Case::TYP),
750 (100, Case::REF),
751 (100, Case::LIT),
752 (100, Case::LTY),
753 (100, Case::OPR),
754 (if rec { 100 } else { 0 }, Case::REC),
755 (90usize.saturating_sub(depth), Case::LAM),
756 (90usize.saturating_sub(depth), Case::SLF),
757 (90usize.saturating_sub(depth), Case::CSE),
758 (90usize.saturating_sub(depth), Case::DAT),
759 (80usize.saturating_sub(2 * depth), Case::APP),
760 (80usize.saturating_sub(2 * depth), Case::ANN),
761 (80usize.saturating_sub(2 * depth), Case::ALL),
762 (30usize.saturating_sub(3 * depth), Case::LET),
763 ];
764
765 match next_case(g, &gens) {
766 Case::TYP => {
767 arena[idx] = Some(Tree::Typ);
768 }
769 Case::REC => {
770 arena[idx] = Some(Tree::Rec);
771 }
772 Case::LTY => {
773 arena[idx] = Some(Tree::LTy(Arbitrary::arbitrary(g)));
774 }
775 Case::LIT => {
776 arena[idx] = Some(Tree::Lit(Arbitrary::arbitrary(g)));
777 }
778 Case::OPR => {
779 arena[idx] = Some(Tree::Opr(Arbitrary::arbitrary(g)));
780 }
781 Case::REF => {
782 arena[idx] = Some(arbitrary_ref(g, defs.clone(), ctx.clone()));
783 }
784 Case::VAR => {
785 let gen = gen_range(g, 0..ctx.len());
786 let n = &ctx[gen];
787 let (i, _) = ctx.iter().enumerate().find(|(_, x)| *x == n).unwrap();
788 arena[idx] = Some(Tree::Var(n.clone(), i as u64));
789 }
790 Case::LAM => {
791 let n = arbitrary_name(g);
792 let mut ctx2 = ctx.clone();
793 ctx2.push_front(n.clone());
794 let bod = arena.len();
795 todo.push(bod);
796 ctxs.push(ctx2);
797 arena.push(None);
798 arena[idx] = Some(Tree::Lam(n, bod));
799 }
800 Case::SLF => {
801 let n = arbitrary_name(g);
802 let mut ctx2 = ctx.clone();
803 ctx2.push_front(n.clone());
804 let bod = arena.len();
805 todo.push(bod);
806 ctxs.push(ctx2);
807 arena.push(None);
808 arena[idx] = Some(Tree::Slf(n, bod));
809 }
810 Case::CSE => {
811 let bod = arena.len();
812 todo.push(bod);
813 ctxs.push(ctx.clone());
814 arena.push(None);
815 arena[idx] = Some(Tree::Cse(bod));
816 }
817 Case::DAT => {
818 let bod = arena.len();
819 todo.push(bod);
820 ctxs.push(ctx.clone());
821 arena.push(None);
822 arena[idx] = Some(Tree::Dat(bod));
823 }
824 Case::APP => {
825 let fun = arena.len();
826 todo.push(fun);
827 ctxs.push(ctx.clone());
828 arena.push(None);
829 let arg = arena.len();
830 todo.push(arg);
831 ctxs.push(ctx.clone());
832 arena.push(None);
833 arena[idx] = Some(Tree::App(fun, arg));
834 }
835 Case::ANN => {
836 let typ = arena.len();
837 todo.push(typ);
838 ctxs.push(ctx.clone());
839 arena.push(None);
840 let trm = arena.len();
841 todo.push(trm);
842 ctxs.push(ctx.clone());
843 arena.push(None);
844 arena[idx] = Some(Tree::Ann(typ, trm));
845 }
846 Case::ALL => {
847 let uses: Uses = Arbitrary::arbitrary(g);
848 let n = arbitrary_name(g);
849 let mut ctx2 = ctx.clone();
850 ctx2.push_front(n.clone());
851 let dom = arena.len();
852 todo.push(dom);
853 ctxs.push(ctx.clone());
854 arena.push(None);
855 let img = arena.len();
856 todo.push(img);
857 ctxs.push(ctx2);
858 arena.push(None);
859 arena[idx] = Some(Tree::All(uses, n, dom, img));
860 }
861 Case::LET => {
862 let letrec: bool = Arbitrary::arbitrary(g);
863 let uses: Uses = Arbitrary::arbitrary(g);
864 let n = arbitrary_name(g);
865 let mut ctx2 = ctx.clone();
866 ctx2.push_front(n.clone());
867 let typ = arena.len();
868 todo.push(typ);
869 ctxs.push(ctx.clone());
870 arena.push(None);
871 let trm = arena.len();
872 todo.push(trm);
873 if letrec {
874 ctxs.push(ctx2.clone());
875 }
876 else {
877 ctxs.push(ctx.clone())
878 };
879 arena.push(None);
880 let bod = arena.len();
881 todo.push(bod);
882 ctxs.push(ctx2.clone());
883 arena.push(None);
884 arena[idx] = Some(Tree::Let(letrec, uses, n, typ, trm, bod));
885 }
886 }
887 }
888 let arena: Vec<Tree> = arena.into_iter().map(|x| x.unwrap()).collect();
890 arena[0].into_term(&arena)
892 }
893
894 impl Arbitrary for Term {
895 fn arbitrary(g: &mut Gen) -> Self {
896 arbitrary_term(g, false, test_defs(), Vector::new())
897 }
898 }
899
900 #[quickcheck]
901 fn term_embed_unembed(x: Term) -> bool {
902 let (a, m) = x.clone().embed();
903 println!("x: {}", x);
904 match Term::unembed(&a, &m) {
905 Ok(y) => {
906 if x == y {
907 true
908 }
909 else {
910 false
913 }
914 }
915 _e => {
916 false
921 }
922 }
923 }
924}