From 04cc5d578821fe44ae527dc216564c448b3ccbbe Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 9 Jul 2023 21:54:32 +0800 Subject: [PATCH 001/229] Add some function from injection paper. --- src/haz3lcore/dynamics/Incon.re | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/haz3lcore/dynamics/Incon.re diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re new file mode 100644 index 0000000000..a5d4b8ded2 --- /dev/null +++ b/src/haz3lcore/dynamics/Incon.re @@ -0,0 +1,39 @@ +let rec matches = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (_, Var(_)) => true + | (_, Wild) => true + | (BoolLit(x), BoolLit(y)) => x == y + | (IntLit(x), IntLit(y)) => x == y + | (FloatLit(x), FloatLit(y)) => x == y + | (StringLit(x), StringLit(y)) => x == y + | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) + // I don't know how to extend the algorithm for projection into that of list or tuples. + | (_, _) => false + }; + +let rec is_val = (e: DHExp.t): bool => + switch (e) { + | BoolLit(_) + | IntLit(_) + | StringLit(_) + | Fun(_, _, _, _) + | ListLit(_, _, _, _, []) + | Tuple([]) => true + | ListLit(_, _, _, _, inner) + | Tuple(inner) => + List.fold_left((last_val, e) => last_val && is_val(e), true, inner) + | BinBoolOp(_, e1, e2) + | BinIntOp(_, e1, e2) + | BinFloatOp(_, e1, e2) + | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false + | Inj(_, _, e) => is_val(e) + | _ => false + }; + +let rec is_indet = (e: DHExp.t): bool => + switch (e) { + | EmptyHole(_, _) => true + | NonEmptyHole(_, _, _, e) => is_final(e) + | _ => false + } +and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); From 1d1b27aec03e9eaa8541d5662c945740ddd44a35 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 16 Jul 2023 11:59:57 +0800 Subject: [PATCH 002/229] Finished implementing algorithms from P8. --- src/haz3lcore/dynamics/Incon.re | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index a5d4b8ded2..2d403e1174 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -7,10 +7,35 @@ let rec matches = (e: DHExp.t, p: DHPat.t): bool => | (FloatLit(x), FloatLit(y)) => x == y | (StringLit(x), StringLit(y)) => x == y | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know how to extend the algorithm for projection into that of list or tuples. + // I don't know if my algorithm is correct or not. + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => true + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) | (_, _) => false }; +let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (BoolLit(x), BoolLit(y)) => x != y + | (IntLit(x), IntLit(y)) => x != y + | (FloatLit(x), FloatLit(y)) => x != y + | (StringLit(x), StringLit(y)) => x != y + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => false + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) + | (Inj(_, side1, x), Inj(side2, y)) => + side1 != side2 || does_not_match(x, y) + | (_, _) => false + }; + +// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. +let indet_match = (e: DHExp.t, p: DHPat.t): bool => + !(matches(e, p) || does_not_match(e, p)); + let rec is_val = (e: DHExp.t): bool => switch (e) { | BoolLit(_) From 092775aba727e12caa8326532a6b1530f8027d58 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Fri, 21 Jul 2023 18:10:34 +0800 Subject: [PATCH 003/229] Translating part of old Constraint.re into this version. --- src/haz3lcore/dynamics/Constraint.re | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/haz3lcore/dynamics/Constraint.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re new file mode 100644 index 0000000000..c94c805f29 --- /dev/null +++ b/src/haz3lcore/dynamics/Constraint.re @@ -0,0 +1,41 @@ +open Sexplib.Std; + +[@deriving sexp] +type t = + | Truth + | Falsity + | Hole + | Int(int) + | NotInt(int) + | Float(float) + | NotFloat(float) + | String(string) + | NotString(string) + | And(t, t) + | Or(t, t) + | InjL(t) + | InjR(t) + | List(list(t)); + +// How to replace this function? +let rec constrains = (c: t, ty: HTyp.t): bool => + switch (c, ty) { + // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { + | (Truth, _) + | (Falsity, _) + | (Hole, _) => true + | (Int(_) | NotInt(_), Int) => true + | (Int(_) | NotInt(_), _) => false + | (Float(_) | NotFloat(_), Float) => true + | (Float(_) | NotFloat(_), _) => false + | (String(_) | NotString(_), String) => true + | (String(_) | NotString(_), _) => false + | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + | (InjL(_), _) => false + | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(_), _) => false + | (List(c), ty) => + List.fold_left((last, x) => last && constrains(x, ty), true, c) + }; From 775d5c8ddefd8a9c9eb7491e3ef68bbab3098c05 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 29 Jul 2023 18:49:58 -0400 Subject: [PATCH 004/229] Init --- src/haz3lcore/statics/Statics.re | 3 +- src/haz3lcore/statics/Term.re | 171 +++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 89f53ff383..c6e10a9ad6 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -49,7 +49,8 @@ let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => let extend_let_def_ctx = (ctx: Ctx.t, pat: UPat.t, pat_ctx: Ctx.t, def: UExp.t): Ctx.t => - if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { + // if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { + if (UExp.is_tuple_of_rec_functions(pat, def)) { pat_ctx; } else { ctx; diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 65720f484f..b64a5f9bc1 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -328,6 +328,28 @@ module UPat = { } ); + let rec has_var_def = (pat: t, var: Var.t) => { + switch (pat.term) { + | Var(var') => var == var' + | Parens(pat) + | TypeAnn(pat, _) + | Ap(_, pat) => has_var_def(pat, var) + | ListLit(pats) + | Tuple(pats) => List.exists(pat => has_var_def(pat, var), pats) + | Cons(pat1, pat2) => has_var_def(pat1, var) || has_var_def(pat2, var) + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Wild + | Int(_) + | Float(_) + | Bool(_) + | String(_) + | Triv + | Constructor(_) => false + }; + }; + let rec get_var = (pat: t) => { switch (pat.term) { | Parens(pat) => get_var(pat) @@ -414,6 +436,29 @@ module UPat = { | Constructor(name) => Some(name) | _ => None }; + + let rec get_pats = (pat: t) => { + switch (pat.term) { + | Parens(pat) => get_pats(pat) + | Tuple(pats) => Some(pats) + // TODO + | Var(_) + | TypeAnn(_) + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Wild + | Int(_) + | Float(_) + | Bool(_) + | String(_) + | Triv + | ListLit(_) + | Cons(_, _) + | Constructor(_) + | Ap(_) => None + }; + }; }; module UExp = { @@ -621,6 +666,132 @@ module UExp = { | _ => [e] }; }; + + let rec is_rec_fun = (pat: UPat.t, e: t) => { + switch (e.term) { + | Parens(e) => is_rec_fun(pat, e) + | Fun(_, e) => + switch (UPat.get_var(pat)) { + | Some(var) => has_fun_var(e, var) + | None => false + } + | _ => false + }; + } + and has_fun_var = (e: t, var: Var.t) => + switch (e.term) { + | Parens(e) + | TyAlias(_, _, e) + | Test(e) + | UnOp(_, e) => has_fun_var(e, var) + | Cons(e1, e2) + | Seq(e1, e2) + | BinOp(_, e1, e2) => has_fun_var(e1, var) || has_fun_var(e2, var) + | If(e1, e2, e3) => + has_fun_var(e1, var) || has_fun_var(e2, var) || has_fun_var(e3, var) + | ListLit(es) + | Tuple(es) => List.exists(has_fun_var(_, var), es) + | Fun(pat, e) + | Let(pat, _, e) => !UPat.has_var_def(pat, var) && has_fun_var(e, var) + | Match(e, ruls) => + has_fun_var(e, var) + || List.exists( + ((pat, e)) => + !UPat.has_var_def(pat, var) && has_fun_var(e, var), + ruls, + ) + | Ap(fn, arg) + | DeferredAp(fn, arg) => + has_branch_var(fn, var) + || has_fun_var(fn, var) + || has_fun_var(arg, var) + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Triv + | Deferral(_) + | Bool(_) + | Int(_) + | Float(_) + | String(_) + | Var(_) + | Constructor(_) => false + } + and has_branch_var = (e: t, var: Var.t) => { + switch (e.term) { + | Var(var') => var == var' + | Parens(e) + | TyAlias(_, _, e) + | Seq(_, e) => has_branch_var(e, var) + | Let(pat, _, e) => + !UPat.has_var_def(pat, var) && has_branch_var(e, var) + | If(_, e1, e2) => has_branch_var(e1, var) || has_branch_var(e2, var) + | Match(_, ruls) => + List.exists( + ((pat, e)) => + !UPat.has_var_def(pat, var) && has_branch_var(e, var), + ruls, + ) + | Ap(_) + | DeferredAp(_) + | Fun(_) + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Triv + | Deferral(_) + | Bool(_) + | Int(_) + | Float(_) + | String(_) + | ListLit(_) + | Tuple(_) + | Test(_) + | Cons(_) + | UnOp(_) + | BinOp(_) + | Constructor(_) => false + }; + }; + + let rec is_tuple_of_rec_functions = (pat: UPat.t, e: t) => { + is_rec_fun(pat, e) + || ( + switch (e.term) { + | Parens(e) => is_tuple_of_rec_functions(pat, e) + | Tuple(es) => + switch (UPat.get_pats(pat)) { + | Some(pats) => + List.for_all(pat => List.exists(is_rec_fun(pat), es), pats) + | None => false + } + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Triv + | Deferral(_) + | Bool(_) + | Int(_) + | Float(_) + | String(_) + | ListLit(_) + | Fun(_) + | Var(_) + | Let(_) + | TyAlias(_) + | Ap(_) + | DeferredAp(_) + | If(_) + | Seq(_) + | Test(_) + | Cons(_) + | UnOp(_) + | BinOp(_) + | Match(_) + | Constructor(_) => false + } + ); + }; }; // TODO(d): consider just folding this into UExp From 59cbf3103aa5e2e19ed01677a641a55cbcf20a80 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 29 Jul 2023 20:19:39 -0400 Subject: [PATCH 005/229] Loosened term constraints --- src/haz3lcore/statics/Term.re | 79 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index b64a5f9bc1..ea3cc587f1 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -680,6 +680,7 @@ module UExp = { } and has_fun_var = (e: t, var: Var.t) => switch (e.term) { + | Var(var') => var == var' | Parens(e) | TyAlias(_, _, e) | Test(e) @@ -702,8 +703,8 @@ module UExp = { ) | Ap(fn, arg) | DeferredAp(fn, arg) => - has_branch_var(fn, var) - || has_fun_var(fn, var) + //has_branch_var(fn, var) || + has_fun_var(fn, var) || has_fun_var(arg, var) | Invalid(_) | EmptyHole @@ -714,45 +715,45 @@ module UExp = { | Int(_) | Float(_) | String(_) - | Var(_) - | Constructor(_) => false - } - and has_branch_var = (e: t, var: Var.t) => { - switch (e.term) { - | Var(var') => var == var' - | Parens(e) - | TyAlias(_, _, e) - | Seq(_, e) => has_branch_var(e, var) - | Let(pat, _, e) => - !UPat.has_var_def(pat, var) && has_branch_var(e, var) - | If(_, e1, e2) => has_branch_var(e1, var) || has_branch_var(e2, var) - | Match(_, ruls) => - List.exists( - ((pat, e)) => - !UPat.has_var_def(pat, var) && has_branch_var(e, var), - ruls, - ) - | Ap(_) - | DeferredAp(_) - | Fun(_) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Triv - | Deferral(_) - | Bool(_) - | Int(_) - | Float(_) - | String(_) - | ListLit(_) - | Tuple(_) - | Test(_) - | Cons(_) - | UnOp(_) - | BinOp(_) + // | Var(_) | Constructor(_) => false }; - }; + // and has_branch_var = (e: t, var: Var.t) => { + // switch (e.term) { + // | Var(var') => var == var' + // | Parens(e) + // | TyAlias(_, _, e) + // | Seq(_, e) => has_branch_var(e, var) + // | Let(pat, _, e) => + // !UPat.has_var_def(pat, var) && has_branch_var(e, var) + // | If(_, e1, e2) => has_branch_var(e1, var) || has_branch_var(e2, var) + // | Match(_, ruls) => + // List.exists( + // ((pat, e)) => + // !UPat.has_var_def(pat, var) && has_branch_var(e, var), + // ruls, + // ) + // | Ap(_) + // | DeferredAp(_) + // | Fun(_) + // | Invalid(_) + // | EmptyHole + // | MultiHole(_) + // | Triv + // | Deferral(_) + // | Bool(_) + // | Int(_) + // | Float(_) + // | String(_) + // | ListLit(_) + // | Tuple(_) + // | Test(_) + // | Cons(_) + // | UnOp(_) + // | BinOp(_) + // | Constructor(_) => false + // }; + // }; let rec is_tuple_of_rec_functions = (pat: UPat.t, e: t) => { is_rec_fun(pat, e) From 438449e715a322baadfd32969265f83c1c640edf Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 29 Jul 2023 20:21:48 -0400 Subject: [PATCH 006/229] Formatted --- src/haz3lcore/statics/Term.re | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index ea3cc587f1..6a464c7bc7 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -703,9 +703,8 @@ module UExp = { ) | Ap(fn, arg) | DeferredAp(fn, arg) => - //has_branch_var(fn, var) || - has_fun_var(fn, var) - || has_fun_var(arg, var) + //has_branch_var(fn, var) || + has_fun_var(fn, var) || has_fun_var(arg, var) | Invalid(_) | EmptyHole | MultiHole(_) From 0911881fe3ae3aa82731074ed97d9374f22caf5f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 29 Jul 2023 23:14:44 -0400 Subject: [PATCH 007/229] Code optimization and bug fixes --- src/haz3lcore/dynamics/Elaborator.re | 3 +- src/haz3lcore/statics/Statics.re | 2 +- src/haz3lcore/statics/Term.re | 47 +++++++++++++++++----------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 97ca224f13..a6f0cb3f00 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -228,7 +228,8 @@ let rec dhexp_of_uexp = let* ddef = dhexp_of_uexp(m, def); let* dbody = dhexp_of_uexp(m, body); let+ ty_body = fixed_exp_typ(m, body); - switch (Term.UPat.get_recursive_bindings(p)) { + //switch (Term.UPat.get_recursive_bindings(p)) { + switch (Term.UExp.get_recursive_bindings(p, def)) { | None => /* not recursive */ DHExp.Let(dp, add_name(Term.UPat.get_var(p), ddef), dbody) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index c6e10a9ad6..889673741b 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -50,7 +50,7 @@ let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => let extend_let_def_ctx = (ctx: Ctx.t, pat: UPat.t, pat_ctx: Ctx.t, def: UExp.t): Ctx.t => // if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { - if (UExp.is_tuple_of_rec_functions(pat, def)) { + if (Option.is_some(UExp.get_recursive_bindings(pat, def))) { pat_ctx; } else { ctx; diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 6a464c7bc7..deb813e363 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -352,9 +352,9 @@ module UPat = { let rec get_var = (pat: t) => { switch (pat.term) { - | Parens(pat) => get_var(pat) + | Parens(pat) + | TypeAnn(pat, _) => get_var(pat) | Var(x) => Some(x) - | TypeAnn(_) | Invalid(_) | EmptyHole | MultiHole(_) @@ -439,11 +439,10 @@ module UPat = { let rec get_pats = (pat: t) => { switch (pat.term) { - | Parens(pat) => get_pats(pat) + | Parens(pat) + | TypeAnn(pat, _) => get_pats(pat) | Tuple(pats) => Some(pats) - // TODO | Var(_) - | TypeAnn(_) | Invalid(_) | EmptyHole | MultiHole(_) @@ -667,15 +666,15 @@ module UExp = { }; }; - let rec is_rec_fun = (pat: UPat.t, e: t) => { + let rec get_fun_var = (pat: UPat.t, e: t) => { switch (e.term) { - | Parens(e) => is_rec_fun(pat, e) + | Parens(e) => get_fun_var(pat, e) | Fun(_, e) => switch (UPat.get_var(pat)) { - | Some(var) => has_fun_var(e, var) - | None => false + | Some(x) when has_fun_var(e, x) => Some(x) + | _ => None } - | _ => false + | _ => None }; } and has_fun_var = (e: t, var: Var.t) => @@ -754,16 +753,28 @@ module UExp = { // }; // }; - let rec is_tuple_of_rec_functions = (pat: UPat.t, e: t) => { - is_rec_fun(pat, e) - || ( + let rec get_recursive_bindings = (pat: UPat.t, e: t) => { + switch (get_fun_var(pat, e)) { + | Some(x) => Some([x]) + | None => switch (e.term) { - | Parens(e) => is_tuple_of_rec_functions(pat, e) + | Parens(e) => get_recursive_bindings(pat, e) | Tuple(es) => switch (UPat.get_pats(pat)) { | Some(pats) => - List.for_all(pat => List.exists(is_rec_fun(pat), es), pats) - | None => false + let get_fun_var = pat => + List.fold_left( + (acc, e) => Option.is_none(acc) ? get_fun_var(pat, e) : acc, + None, + es, + ); + let fun_vars = pats |> List.map(get_fun_var); + if (List.exists(Option.is_none, fun_vars)) { + None; + } else { + Some(List.map(Option.get, fun_vars)); + }; + | None => None } | Invalid(_) | EmptyHole @@ -788,9 +799,9 @@ module UExp = { | UnOp(_) | BinOp(_) | Match(_) - | Constructor(_) => false + | Constructor(_) => None } - ); + }; }; }; From ea3d8fdbd6fbc55efef64538d954fb9cc69140bd Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 30 Jul 2023 13:15:29 -0400 Subject: [PATCH 008/229] Fixed the info map bug for recursive cases --- src/haz3lcore/statics/Statics.re | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 889673741b..47ee34751c 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -247,9 +247,22 @@ and uexp_to_info_map = ); | Let(p, def, body) => let (p_syn, _) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); - let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); - let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; - let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); + let (def, p_ana, m) = + if (Option.is_none(UExp.get_recursive_bindings(p, def))) { + let (def, m) = go(~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + let (p_ana, m) = + go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); + (def, p_ana, m); + } else { + let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + let (p_ana, m) = + go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); + let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); + (def, p_ana, m); + }; + // let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); + // let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + // let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); add( ~self=Just(body.ty), From f6f7bd84394f3882352d45892986e3b48bffa1c9 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 30 Jul 2023 14:37:40 -0400 Subject: [PATCH 009/229] Small fix --- src/haz3lcore/statics/Statics.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 47ee34751c..b8c3d494cf 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -257,7 +257,7 @@ and uexp_to_info_map = let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); - let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); + let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_ana.ty), def, m); (def, p_ana, m); }; // let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); From 551b07e33a9d03d1b3ce640f94b5aa16ae1f8e8d Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 30 Jul 2023 23:31:02 -0400 Subject: [PATCH 010/229] Update Term.re DeferredAp --- src/haz3lcore/statics/Term.re | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index deb813e363..fb783e5ae2 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -700,10 +700,12 @@ module UExp = { !UPat.has_var_def(pat, var) && has_fun_var(e, var), ruls, ) - | Ap(fn, arg) - | DeferredAp(fn, arg) => + | Ap(fn, arg) => //has_branch_var(fn, var) || has_fun_var(fn, var) || has_fun_var(arg, var) + | DeferredAp(fn, args) => + //has_branch_var(fn, var) || + has_fun_var(fn, var) || List.exists(has_fun_var(_, var), args) | Invalid(_) | EmptyHole | MultiHole(_) From d714115d4acdb00c7071dc151cb1dfc0221e8537 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Tue, 1 Aug 2023 21:16:36 +0800 Subject: [PATCH 011/229] Rebase the project on `adt_defs_after` instead of `dev`. --- src/haz3lcore/Measured.re | 14 +- src/haz3lcore/dynamics/Builtins.re | 129 +- src/haz3lcore/dynamics/Builtins.rei | 11 + src/haz3lcore/dynamics/DH.re | 26 +- src/haz3lcore/dynamics/DHPat.re | 8 +- .../dynamics/{elaborator.re => Elaborator.re} | 304 +- src/haz3lcore/dynamics/Evaluator.re | 297 +- src/haz3lcore/dynamics/EvaluatorPost.re | 25 +- src/haz3lcore/dynamics/HTyp.re | 190 - src/haz3lcore/dynamics/HTyp.rei | 39 - .../dynamics/InvalidOperationError.re | 4 + .../dynamics/InvalidOperationError.rei | 2 + src/haz3lcore/dynamics/ListErrStatus.re | 6 - src/haz3lcore/dynamics/Substitution.re | 9 +- src/haz3lcore/lang/Form.re | 46 +- src/haz3lcore/lang/Sort.re | 14 +- src/haz3lcore/statics/BuiltinADTs.re | 97 - src/haz3lcore/statics/CoCtx.re | 61 + src/haz3lcore/statics/Constructor.re | 6 + src/haz3lcore/statics/ConstructorMap.re | 101 + src/haz3lcore/statics/Ctx.re | 109 +- src/haz3lcore/statics/Info.re | 480 ++ src/haz3lcore/statics/Kind.re | 4 +- src/haz3lcore/statics/MakeTerm.re | 168 +- src/haz3lcore/statics/Mode.re | 126 + src/haz3lcore/statics/Self.re | 90 + src/haz3lcore/statics/Statics.re | 927 +-- src/haz3lcore/statics/Term.re | 292 +- src/haz3lcore/statics/TermBase.re | 156 +- src/haz3lcore/statics/Typ.re | 247 +- src/haz3lcore/statics/TypBase.re | 606 ++ src/haz3lcore/statics/TypVar.re | 6 + src/haz3lcore/{dynamics => statics}/Var.re | 0 src/haz3lcore/tiles/Id.re | 67 + src/haz3lcore/tiles/Segment.re | 21 + src/haz3lcore/tiles/Skel.re | 7 +- src/haz3lcore/zipper/Editor.re | 4 +- src/haz3lcore/zipper/EditorUtil.re | 5 +- src/haz3lcore/zipper/action/Perform.re | 5 +- .../{SchoolExercise.re => Exercise.re} | 21 +- src/haz3lschool/GradePrelude.re | 4 +- src/haz3lschool/Gradescope.re | 10 +- src/haz3lschool/Grading.re | 4 +- src/haz3lweb/DebugAction.re | 8 +- src/haz3lweb/Editors.re | 115 +- .../{SchoolExercise.re => Exercise.re} | 2 +- src/haz3lweb/ExerciseSettings.re | 2 + ...tings_base.re => ExerciseSettings_base.re} | 2 +- src/haz3lweb/ExerciseSettings_instructor.re | 2 + src/haz3lweb/ExerciseSettings_student.re | 2 + src/haz3lweb/Export.re | 35 +- src/haz3lweb/Grading.re | 2 +- src/haz3lweb/Init.ml | 7336 +++++++++++++++++ src/haz3lweb/Keyboard.re | 28 +- src/haz3lweb/LangDocMessages.re | 257 +- src/haz3lweb/LanguageRefSlide.ml | 1069 --- src/haz3lweb/Log.re | 10 +- src/haz3lweb/Main.re | 4 +- src/haz3lweb/Model.re | 59 +- src/haz3lweb/ModelSettings.re | 33 +- src/haz3lweb/PersistentData.re | 14 + src/haz3lweb/School.re | 11 - src/haz3lweb/SchoolSettings.re | 2 - src/haz3lweb/SchoolSettings_instructor.re | 2 - src/haz3lweb/SchoolSettings_student.re | 2 - src/haz3lweb/ScratchSlidesInit.re | 25 - src/haz3lweb/{LocalStorage.re => Store.re} | 140 +- src/haz3lweb/Update.re | 367 +- src/haz3lweb/UpdateAction.re | 10 +- src/haz3lweb/exercises/BlankTemplate.ml | 2 +- src/haz3lweb/exercises/Ex_OddlyRecursive.ml | 2 +- .../exercises/Ex_RecursiveFibonacci.ml | 2 +- src/haz3lweb/view/BackpackView.re | 2 +- src/haz3lweb/view/Cell.re | 4 +- src/haz3lweb/view/CtxInspector.re | 102 +- src/haz3lweb/view/CursorInspector.re | 451 +- src/haz3lweb/view/DebugMode.re | 2 +- src/haz3lweb/view/Deco.re | 4 +- src/haz3lweb/view/EditorModeView.re | 83 + .../view/{SchoolMode.re => ExerciseMode.re} | 73 +- src/haz3lweb/view/Icons.re | 16 + src/haz3lweb/view/Kind.re | 16 +- src/haz3lweb/view/LangDoc.re | 147 +- src/haz3lweb/view/Page.re | 337 +- src/haz3lweb/view/ScratchMode.re | 50 +- src/haz3lweb/view/Type.re | 44 +- src/haz3lweb/view/dec/PieceDec.re | 22 +- src/haz3lweb/view/dhcode/DHCode.re | 36 +- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 25 +- src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re | 12 +- src/haz3lweb/view/dhcode/layout/DHDoc_Util.re | 114 + .../view/dhcode/layout/DHDoc_common.re | 37 +- .../view/dhcode/layout/DHDoc_common.rei | 7 +- src/haz3lweb/view/dhcode/layout/HTypDoc.re | 36 +- src/haz3lweb/www/index.html | 12 +- src/haz3lweb/www/style.css | 936 ++- src/util/ListUtil.re | 6 + 97 files changed, 12360 insertions(+), 4507 deletions(-) rename src/haz3lcore/dynamics/{elaborator.re => Elaborator.re} (57%) delete mode 100644 src/haz3lcore/dynamics/HTyp.re delete mode 100644 src/haz3lcore/dynamics/HTyp.rei delete mode 100644 src/haz3lcore/dynamics/ListErrStatus.re delete mode 100644 src/haz3lcore/statics/BuiltinADTs.re create mode 100644 src/haz3lcore/statics/CoCtx.re create mode 100644 src/haz3lcore/statics/Constructor.re create mode 100644 src/haz3lcore/statics/ConstructorMap.re create mode 100644 src/haz3lcore/statics/Info.re create mode 100644 src/haz3lcore/statics/Mode.re create mode 100644 src/haz3lcore/statics/Self.re create mode 100644 src/haz3lcore/statics/TypBase.re create mode 100644 src/haz3lcore/statics/TypVar.re rename src/haz3lcore/{dynamics => statics}/Var.re (100%) rename src/haz3lschool/{SchoolExercise.re => Exercise.re} (98%) rename src/haz3lweb/{SchoolExercise.re => Exercise.re} (80%) create mode 100644 src/haz3lweb/ExerciseSettings.re rename src/haz3lweb/{SchoolSettings_base.re => ExerciseSettings_base.re} (72%) create mode 100644 src/haz3lweb/ExerciseSettings_instructor.re create mode 100644 src/haz3lweb/ExerciseSettings_student.re create mode 100644 src/haz3lweb/Init.ml delete mode 100644 src/haz3lweb/LanguageRefSlide.ml create mode 100644 src/haz3lweb/PersistentData.re delete mode 100644 src/haz3lweb/School.re delete mode 100644 src/haz3lweb/SchoolSettings.re delete mode 100644 src/haz3lweb/SchoolSettings_instructor.re delete mode 100644 src/haz3lweb/SchoolSettings_student.re delete mode 100644 src/haz3lweb/ScratchSlidesInit.re rename src/haz3lweb/{LocalStorage.re => Store.re} (65%) create mode 100644 src/haz3lweb/view/EditorModeView.re rename src/haz3lweb/view/{SchoolMode.re => ExerciseMode.re} (88%) create mode 100644 src/haz3lweb/view/dhcode/layout/DHDoc_Util.re diff --git a/src/haz3lcore/Measured.re b/src/haz3lcore/Measured.re index 77f7697401..68ac8a8ace 100644 --- a/src/haz3lcore/Measured.re +++ b/src/haz3lcore/Measured.re @@ -183,8 +183,8 @@ let find_g = (g: Grout.t, map): measurement => Id.Map.find(g.id, map.grout); // returns the measurement spanning the whole tile let find_t = (t: Tile.t, map): measurement => { let shards = Id.Map.find(t.id, map.tiles); - let first = List.assoc(Tile.l_shard(t), shards); - let last = List.assoc(Tile.r_shard(t), shards); + let first = ListUtil.assoc_err(Tile.l_shard(t), shards, "find_t"); + let last = ListUtil.assoc_err(Tile.r_shard(t), shards, "find_t"); {origin: first.origin, last: last.last}; }; // let find_a = ({shards: (l, r), _} as a: Ancestor.t, map) => @@ -206,8 +206,14 @@ let find_by_id = (id: Id.t, map: t): option(measurement) => { | None => switch (Id.Map.find_opt(id, map.tiles)) { | Some(shards) => - let first = List.assoc(List.hd(shards) |> fst, shards); - let last = List.assoc(ListUtil.last(shards) |> fst, shards); + let first = + ListUtil.assoc_err(List.hd(shards) |> fst, shards, "find_by_id"); + let last = + ListUtil.assoc_err( + ListUtil.last(shards) |> fst, + shards, + "find_by_id", + ); Some({origin: first.origin, last: last.last}); | None => Printf.printf("Measured.WARNING: id %d not found", id); diff --git a/src/haz3lcore/dynamics/Builtins.re b/src/haz3lcore/dynamics/Builtins.re index 5ee5f48796..3a8ed5ee85 100644 --- a/src/haz3lcore/dynamics/Builtins.re +++ b/src/haz3lcore/dynamics/Builtins.re @@ -34,6 +34,57 @@ module Pervasives = { open EvaluatorMonad; open EvaluatorResult; + /* is_finite implementation. */ + let is_finite = (name, r1) => + switch (r1) { + | BoxedValue(FloatLit(f)) => + let b = Float.is_finite(f); + BoxedValue(BoolLit(b)) |> return; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedFloatLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* is_infinite implementation. */ + let is_infinite = (name, r1) => + switch (r1) { + | BoxedValue(FloatLit(f)) => + let b = Float.is_infinite(f); + BoxedValue(BoolLit(b)) |> return; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedFloatLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* is_NaN implementation. */ + let is_nan = (name, r1) => + switch (r1) { + | BoxedValue(FloatLit(f)) => + let b = Float.is_nan(f); + BoxedValue(BoolLit(b)) |> return; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedFloatLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* int_of_string implementation. */ + let int_of_string = (name, r1) => + switch (r1) { + | BoxedValue(StringLit(f) as d1) => + let i = int_of_string_opt(f); + switch (i) { + | Some(x) => BoxedValue(IntLit(x)) |> return + | None => + Indet( + InvalidOperation(ApBuiltin(name, [d1]), InvalidIntOfString), + ) + |> return + }; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedStringLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + /* int_of_float implementation. */ let int_of_float = (name, r1) => switch (r1) { @@ -41,7 +92,7 @@ module Pervasives = { let i = int_of_float(f); BoxedValue(IntLit(i)) |> return; | BoxedValue(d1) => - raise(EvaluatorError.Exception(InvalidBoxedIntLit(d1))) + raise(EvaluatorError.Exception(InvalidBoxedFloatLit(d1))) | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return }; @@ -52,7 +103,47 @@ module Pervasives = { let f = float_of_int(i); BoxedValue(FloatLit(f)) |> return; | BoxedValue(d1) => - raise(EvaluatorError.Exception(InvalidBoxedFloatLit(d1))) + raise(EvaluatorError.Exception(InvalidBoxedIntLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* float_of_string implementation. */ + let float_of_string = (name, r1) => + switch (r1) { + | BoxedValue(StringLit(s) as d1) => + let f = float_of_string_opt(s); + switch (f) { + | Some(x) => BoxedValue(FloatLit(x)) |> return + | None => + Indet( + InvalidOperation(ApBuiltin(name, [d1]), InvalidFloatOfString), + ) + |> return + }; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedStringLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* string_of_int implementation. */ + let string_of_int = (name, r1) => + switch (r1) { + | BoxedValue(IntLit(i)) => + let s = string_of_int(i); + BoxedValue(StringLit(s)) |> return; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedIntLit(d1))) + | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return + }; + + /* string_of_float implementation. */ + let string_of_float = (name, r1) => + switch (r1) { + | BoxedValue(FloatLit(f)) => + let s = string_of_float(f); + BoxedValue(StringLit(s)) |> return; + | BoxedValue(d1) => + raise(EvaluatorError.Exception(InvalidBoxedIntLit(d1))) | Indet(d1) => Indet(ApBuiltin(name, [d1])) |> return }; @@ -73,20 +164,54 @@ module Pervasives = { /* PI implementation. */ let pi = DHExp.FloatLit(Float.pi); + + /* Infinity-float implementation. */ + let infinity = DHExp.FloatLit(Float.infinity); + let neg_infinity = DHExp.FloatLit(Float.neg_infinity); + + /* NaN float implementation. */ + let nan = DHExp.FloatLit(Float.nan); }; let pi = name => Builtin.mk_zero(name, Float, Impls.pi); + let infinity = name => Builtin.mk_zero(name, Float, Impls.infinity); + let neg_infinity = name => Builtin.mk_zero(name, Float, Impls.neg_infinity); + let nan = name => Builtin.mk_zero(name, Float, Impls.nan); + let is_finite = name => + Builtin.mk_one(name, Arrow(Float, Bool), Impls.is_finite); + let is_infinite = name => + Builtin.mk_one(name, Arrow(Float, Bool), Impls.is_infinite); + let is_nan = name => + Builtin.mk_one(name, Arrow(Float, Bool), Impls.is_nan); let int_of_float = name => Builtin.mk_one(name, Arrow(Float, Int), Impls.int_of_float); + let int_of_string = name => + Builtin.mk_one(name, Arrow(String, Int), Impls.int_of_string); let float_of_int = name => Builtin.mk_one(name, Arrow(Int, Float), Impls.float_of_int); + let float_of_string = name => + Builtin.mk_one(name, Arrow(String, Float), Impls.float_of_string); + let string_of_float = name => + Builtin.mk_one(name, Arrow(Float, String), Impls.string_of_float); + let string_of_int = name => + Builtin.mk_one(name, Arrow(Int, String), Impls.string_of_int); let modulo = name => Builtin.mk_one(name, Arrow(Prod([Int, Int]), Int), Impls.int_mod); let builtins = VarMap.empty |> using("pi", pi) + |> using("infinity", infinity) + |> using("neg_infinity", neg_infinity) + |> using("nan", nan) + |> using("is_finite", is_finite) + |> using("is_infinite", is_infinite) + |> using("is_nan", is_nan) |> using("int_of_float", int_of_float) + |> using("int_of_string", int_of_string) |> using("float_of_int", float_of_int) + |> using("float_of_string", float_of_string) + |> using("string_of_int", string_of_int) + |> using("string_of_float", string_of_float) |> using("mod", modulo); }; diff --git a/src/haz3lcore/dynamics/Builtins.rei b/src/haz3lcore/dynamics/Builtins.rei index 51c66c08e5..ecedb94373 100644 --- a/src/haz3lcore/dynamics/Builtins.rei +++ b/src/haz3lcore/dynamics/Builtins.rei @@ -25,9 +25,20 @@ let using: (Var.t, Var.t => Builtin.t, t) => t; */ module Pervasives: { let pi: Var.t => Builtin.t; + let infinity: Var.t => Builtin.t; + let neg_infinity: Var.t => Builtin.t; + let nan: Var.t => Builtin.t; + + let is_finite: Var.t => Builtin.t; + let is_infinite: Var.t => Builtin.t; + let is_nan: Var.t => Builtin.t; let int_of_float: Var.t => Builtin.t; + let int_of_string: Var.t => Builtin.t; let float_of_int: Var.t => Builtin.t; + let float_of_string: Var.t => Builtin.t; + let string_of_int: Var.t => Builtin.t; + let string_of_float: Var.t => Builtin.t; let modulo: Var.t => Builtin.t; let builtins: t; diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index ec00933ed3..883ebe051f 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -69,12 +69,11 @@ module rec DHExp: { | BinIntOp(BinIntOp.t, t, t) | BinFloatOp(BinFloatOp.t, t, t) | BinStringOp(BinStringOp.t, t, t) - | ListLit(MetaVar.t, MetaVarInst.t, ListErrStatus.t, Typ.t, list(t)) + | ListLit(MetaVar.t, MetaVarInst.t, Typ.t, list(t)) | Cons(t, t) | Tuple(list(t)) | Prj(t, int) - | Inj(Typ.t, InjSide.t, t) - | Tag(string) + | Constructor(string) | ConsistentCase(case) | Cast(t, Typ.t, Typ.t) | FailedCast(t, Typ.t, Typ.t) @@ -166,12 +165,11 @@ module rec DHExp: { | BinIntOp(BinIntOp.t, t, t) | BinFloatOp(BinFloatOp.t, t, t) | BinStringOp(BinStringOp.t, t, t) - | ListLit(MetaVar.t, MetaVarInst.t, ListErrStatus.t, Typ.t, list(t)) + | ListLit(MetaVar.t, MetaVarInst.t, Typ.t, list(t)) | Cons(t, t) | Tuple(list(t)) | Prj(t, int) - | Inj(Typ.t, InjSide.t, t) - | Tag(string) + | Constructor(string) | ConsistentCase(case) | Cast(t, Typ.t, Typ.t) | FailedCast(t, Typ.t, Typ.t) @@ -209,8 +207,7 @@ module rec DHExp: { | Cons(_, _) => "Cons" | Tuple(_) => "Tuple" | Prj(_) => "Prj" - | Inj(_, _, _) => "Inj" - | Tag(_) => "Tag" + | Constructor(_) => "Constructor" | ConsistentCase(_) => "ConsistentCase" | InconsistentBranches(_, _, _) => "InconsistentBranches" | Cast(_, _, _) => "Cast" @@ -239,12 +236,10 @@ module rec DHExp: { | Closure(ei, d) => Closure(ei, strip_casts(d)) | Cast(d, _, _) => strip_casts(d) | FailedCast(d, _, _) => strip_casts(d) - | Inj(ty, side, d) => Inj(ty, side, strip_casts(d)) | Tuple(ds) => Tuple(ds |> List.map(strip_casts)) | Prj(d, n) => Prj(strip_casts(d), n) | Cons(d1, d2) => Cons(strip_casts(d1), strip_casts(d2)) - | ListLit(a, b, c, d, ds) => - ListLit(a, b, c, d, List.map(strip_casts, ds)) + | ListLit(a, b, c, ds) => ListLit(a, b, c, List.map(strip_casts, ds)) | NonEmptyHole(err, u, i, d) => NonEmptyHole(err, u, i, strip_casts(d)) | Sequence(a, b) => Sequence(strip_casts(a), strip_casts(b)) | Let(dp, b, c) => Let(dp, strip_casts(b), strip_casts(c)) @@ -277,7 +272,7 @@ module rec DHExp: { | IntLit(_) as d | FloatLit(_) as d | StringLit(_) as d - | Tag(_) as d + | Constructor(_) as d | InvalidOperation(_) as d => d and strip_casts_rule = (Rule(a, d)) => Rule(a, strip_casts(d)); @@ -290,7 +285,7 @@ module rec DHExp: { | (BoolLit(_), _) | (IntLit(_), _) | (FloatLit(_), _) - | (Tag(_), _) => d1 == d2 + | (Constructor(_), _) => d1 == d2 | (StringLit(s1), StringLit(s2)) => String.equal(s1, s2) | (StringLit(_), _) => false @@ -312,7 +307,7 @@ module rec DHExp: { | (Prj(d1, n), Prj(d2, m)) => n == m && fast_equal(d1, d2) | (ApBuiltin(f1, args1), ApBuiltin(f2, args2)) => f1 == f2 && List.for_all2(fast_equal, args1, args2) - | (ListLit(_, _, _, _, ds1), ListLit(_, _, _, _, ds2)) => + | (ListLit(_, _, _, ds1), ListLit(_, _, _, ds2)) => List.for_all2(fast_equal, ds1, ds2) | (BinBoolOp(op1, d11, d21), BinBoolOp(op2, d12, d22)) => op1 == op2 && fast_equal(d11, d12) && fast_equal(d21, d22) @@ -322,8 +317,6 @@ module rec DHExp: { op1 == op2 && fast_equal(d11, d12) && fast_equal(d21, d22) | (BinStringOp(op1, d11, d21), BinStringOp(op2, d12, d22)) => op1 == op2 && fast_equal(d11, d12) && fast_equal(d21, d22) - | (Inj(ty1, side1, d1), Inj(ty2, side2, d2)) => - ty1 == ty2 && side1 == side2 && fast_equal(d1, d2) | (Cast(d1, ty11, ty21), Cast(d2, ty12, ty22)) | (FailedCast(d1, ty11, ty21), FailedCast(d2, ty12, ty22)) => fast_equal(d1, d2) && ty11 == ty12 && ty21 == ty22 @@ -347,7 +340,6 @@ module rec DHExp: { | (BinIntOp(_), _) | (BinFloatOp(_), _) | (BinStringOp(_), _) - | (Inj(_), _) | (Cast(_), _) | (FailedCast(_), _) | (InvalidOperation(_), _) diff --git a/src/haz3lcore/dynamics/DHPat.re b/src/haz3lcore/dynamics/DHPat.re index b2654aee0c..0cac9b9814 100644 --- a/src/haz3lcore/dynamics/DHPat.re +++ b/src/haz3lcore/dynamics/DHPat.re @@ -7,16 +7,16 @@ type t = | Wild | ExpandingKeyword(MetaVar.t, MetaVarInst.t, ExpandingKeyword.t) | InvalidText(MetaVar.t, MetaVarInst.t, string) + | BadConstructor(MetaVar.t, MetaVarInst.t, string) | Var(Var.t) | IntLit(int) | FloatLit(float) | BoolLit(bool) | StringLit(string) - | Inj(InjSide.t, t) | ListLit(Typ.t, list(t)) | Cons(t, t) | Tuple(list(t)) - | Tag(string) + | Constructor(string) | Ap(t, t); let mk_tuple: list(t) => t = @@ -34,14 +34,14 @@ let rec binds_var = (x: Var.t, dp: t): bool => | NonEmptyHole(_, _, _, _) | Wild | InvalidText(_) + | BadConstructor(_) | IntLit(_) | FloatLit(_) | BoolLit(_) | StringLit(_) - | Tag(_) + | Constructor(_) | ExpandingKeyword(_, _, _) => false | Var(y) => Var.eq(x, y) - | Inj(_, dp1) => binds_var(x, dp1) | Tuple(dps) => dps |> List.exists(binds_var(x)) | Cons(dp1, dp2) => binds_var(x, dp1) || binds_var(x, dp2) | ListLit(_, d_list) => diff --git a/src/haz3lcore/dynamics/elaborator.re b/src/haz3lcore/dynamics/Elaborator.re similarity index 57% rename from src/haz3lcore/dynamics/elaborator.re rename to src/haz3lcore/dynamics/Elaborator.re index c4027cfc8d..fc3cb3e772 100644 --- a/src/haz3lcore/dynamics/elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -43,7 +43,7 @@ let bool_op_of: Term.UExp.op_bin_bool => DHExp.BinBoolOp.t = | And => And | Or => Or; -let exp_binop_of: Term.UExp.op_bin => (HTyp.t, (_, _) => DHExp.t) = +let exp_binop_of: Term.UExp.op_bin => (Typ.t, (_, _) => DHExp.t) = fun | Int(op) => (Int, ((e1, e2) => BinIntOp(int_op_of(op), e1, e2))) | Float(op) => (Float, ((e1, e2) => BinFloatOp(float_op_of(op), e1, e2))) @@ -53,116 +53,124 @@ let exp_binop_of: Term.UExp.op_bin => (HTyp.t, (_, _) => DHExp.t) = ((e1, e2) => BinStringOp(string_op_of(op), e1, e2)), ); -/* Wrap: Handles cast insertion and non-empty-hole wrapping +let fixed_exp_typ = (m: Statics.Map.t, e: Term.UExp.t): option(Typ.t) => + switch (Id.Map.find_opt(Term.UExp.rep_id(e), m)) { + | Some(InfoExp({ty, _})) => Some(ty) + | _ => None + }; + +let fixed_pat_typ = (m: Statics.Map.t, p: Term.UPat.t): option(Typ.t) => + switch (Id.Map.find_opt(Term.UPat.rep_id(p), m)) { + | Some(InfoPat({ty, _})) => Some(ty) + | _ => None + }; + +let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => + switch (mode) { + | Syn => d + | SynFun => + switch (self_ty) { + | Unknown(prov) => + DHExp.cast(d, Unknown(prov), Arrow(Unknown(prov), Unknown(prov))) + | Arrow(_) => d + | _ => failwith("Elaborator.wrap: SynFun non-arrow-type") + } + | Ana(ana_ty) => + let ana_ty = Typ.normalize(ctx, ana_ty); + /* Forms with special ana rules get cast from their appropriate Matched types */ + switch (d) { + | ListLit(_) + | Cons(_) => + switch (ana_ty) { + | Unknown(prov) => DHExp.cast(d, List(Unknown(prov)), Unknown(prov)) + | _ => d + } + | Fun(_) => + switch (ana_ty) { + //| Unknown(prov) => + // DHExp.cast(d, Arrow(Unknown(prov), Unknown(prov)), Unknown(prov)) + | ana_ty => + /* See regression tests in Examples/Dynamics */ + let (_, ana_out) = Typ.matched_arrow(ana_ty); + let (self_in, _) = Typ.matched_arrow(self_ty); + DHExp.cast(d, Arrow(self_in, ana_out), ana_ty); + } + | Tuple(ds) => + switch (ana_ty) { + | Unknown(prov) => + let us = List.init(List.length(ds), _ => Typ.Unknown(prov)); + DHExp.cast(d, Prod(us), Unknown(prov)); + | _ => d + } + | Ap(Constructor(_), _) + | Constructor(_) => + switch (ana_ty, self_ty) { + | (Unknown(prov), Rec(_, Sum(_))) + | (Unknown(prov), Sum(_)) => DHExp.cast(d, self_ty, Unknown(prov)) + | _ => d + } + /* Forms with special ana rules but no particular typing requirements */ + | ConsistentCase(_) + | InconsistentBranches(_) + | Sequence(_) + | Let(_) + | FixF(_) => d + /* Hole-like forms: Don't cast */ + | InvalidText(_) + | FreeVar(_) + | ExpandingKeyword(_) + | EmptyHole(_) + | NonEmptyHole(_) => d + /* DHExp-specific forms: Don't cast */ + | Cast(_) + | Closure(_) + | FailedCast(_) + | InvalidOperation(_) => d + /* Normal cases: wrap */ + | BoundVar(_) + | Ap(_) + | ApBuiltin(_) + | Prj(_) + | BoolLit(_) + | IntLit(_) + | FloatLit(_) + | StringLit(_) + | BinBoolOp(_) + | BinIntOp(_) + | BinFloatOp(_) + | BinStringOp(_) + | TestLit(_) => DHExp.cast(d, self_ty, ana_ty) + }; + }; + +/* Handles cast insertion and non-empty-hole wrapping for elaborated expressions */ -let wrap = (u, mode, self, d: DHExp.t): option(DHExp.t) => - switch (Statics.error_status(mode, self)) { +let wrap = (ctx: Ctx.t, u: Id.t, mode: Mode.t, self, d: DHExp.t): DHExp.t => + switch (Info.status_exp(ctx, mode, self)) { | NotInHole(_) => - switch (mode) { - | Syn => Some(d) - | SynFun => - /* Things in function position get cast to the matched arrow type */ - let ty_self = Typ.t_of_self(self); - switch (ty_self) { - | Unknown(prov) => - Some(DHExp.cast(d, ty_self, Arrow(Unknown(prov), Unknown(prov)))) - | Arrow(_) => Some(d) - | _ => failwith("Elaborator.wrap: SynFun non-arrow-type") + let self_ty = + switch (Self.typ_of_exp(ctx, self)) { + | Some(self_ty) => Typ.normalize(ctx, self_ty) + | None => Unknown(Internal) }; - | Ana(ana_ty) => - /* Forms with special ana rules get cast from their appropriate Matched types */ - switch (d) { - | ListLit(_) - | Cons(_) => - switch (ana_ty) { - | Unknown(prov) => - Some(DHExp.cast(d, List(Unknown(prov)), ana_ty)) - | _ => Some(d) - } - | Fun(_) => - switch (ana_ty) { - | Unknown(prov) => - Some(DHExp.cast(d, Arrow(Unknown(prov), Unknown(prov)), ana_ty)) - | _ => Some(d) - } - | Tuple(ds) => - switch (ana_ty) { - | Unknown(prov) => - let us = List.init(List.length(ds), _ => Typ.Unknown(prov)); - Some(DHExp.cast(d, Prod(us), ana_ty)); - | _ => Some(d) - } - | Inj(_) => - switch (ana_ty) { - | Unknown(prov) => - Some(DHExp.cast(d, Sum(Unknown(prov), Unknown(prov)), ana_ty)) - | _ => Some(d) - } - /* Forms with special ana rules but no particular typing requirements */ - | ConsistentCase(_) - | InconsistentBranches(_) - | Sequence(_) - | Let(_) - | FixF(_) => Some(d) - /* Hole-like forms: Don't cast */ - | InvalidText(_) - | FreeVar(_) - | ExpandingKeyword(_) - | EmptyHole(_) - | NonEmptyHole(_) => Some(d) - /* DHExp-specific forms: Don't cast */ - | Cast(_) - | Closure(_) - | FailedCast(_) - | InvalidOperation(_) => Some(d) - /* Normal cases: wrap */ - | BoundVar(_) - | Ap(_) - | ApBuiltin(_) - | Prj(_) - | Tag(_) - | BoolLit(_) - | IntLit(_) - | FloatLit(_) - | StringLit(_) - | BinBoolOp(_) - | BinIntOp(_) - | BinFloatOp(_) - | BinStringOp(_) - | TestLit(_) => Some(DHExp.cast(d, Typ.t_of_self(self), ana_ty)) - } - } - | InHole(_) => Some(NonEmptyHole(TypeInconsistent, u, 0, d)) + cast(ctx, mode, self_ty, d); + | InHole(_) => NonEmptyHole(TypeInconsistent, u, 0, d) }; -let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => { - /* NOTE: Left out delta for now */ +let rec dhexp_of_uexp = + (m: Statics.Map.t, uexp: Term.UExp.t): option(DHExp.t) => { switch (Id.Map.find_opt(Term.UExp.rep_id(uexp), m)) { - | Some(InfoExp({mode, self, _})) => - let err_status = Statics.error_status(mode, self); + | Some(InfoExp({mode, self, ctx, _})) => + let err_status = Info.status_exp(ctx, mode, self); let id = Term.UExp.rep_id(uexp); /* NOTE: using term uids for hole ids */ - let* d: DHExp.t = + let+ d: DHExp.t = switch (uexp.term) { - | Invalid(_) /* NOTE: treating invalid as a hole for now */ + | Invalid(t) => Some(DHExp.InvalidText(id, 0, t)) | EmptyHole => Some(DHExp.EmptyHole(id, 0)) | MultiHole(_tms) => /* TODO: add a dhexp case and eval logic for multiholes. Make sure new dhexp form is properly considered Indet to avoid casting issues. */ - /*let+ ds = - tms - |> List.map( - fun - | Term.Exp(e) => dhexp_of_uexp(m, e) - | tm => Some(EmptyHole(Term.rep_id(tm), 0)), - ) - |> OptUtil.sequence; - switch (ds) { - | [] => DHExp.EmptyHole(id, 0) - | [hd, ...tl] => - // TODO: placeholder logic: sequence - tl |> List.fold_left((acc, d) => DHExp.Sequence(d, acc), hd) - };*/ Some(EmptyHole(id, 0)) | Triv => Some(Tuple([])) | Bool(b) => Some(BoolLit(b)) @@ -170,27 +178,18 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => | Float(n) => Some(FloatLit(n)) | String(s) => Some(StringLit(s)) | ListLit(es) => - let+ ds = es |> List.map(dhexp_of_uexp(m)) |> OptUtil.sequence; - let ty = Statics.exp_typ(m, uexp) |> Typ.matched_list; - //TODO: why is there an err status on below? - DHExp.ListLit(id, 0, StandardErrStatus(NotInHole), ty, ds); + let* ds = es |> List.map(dhexp_of_uexp(m)) |> OptUtil.sequence; + let+ ty = fixed_exp_typ(m, uexp); + let ty = Typ.matched_list(ty); + DHExp.ListLit(id, 0, ty, ds); | Fun(p, body) => let* dp = dhpat_of_upat(m, p); - let+ d1 = dhexp_of_uexp(m, body); - DHExp.Fun(dp, Statics.pat_typ(m, p), d1, None); + let* d1 = dhexp_of_uexp(m, body); + let+ ty = fixed_pat_typ(m, p); + DHExp.Fun(dp, ty, d1, None); | Tuple(es) => - let+ ds = - List.fold_right( - (e, ds_opt) => { - let* ds = ds_opt; - let+ d = dhexp_of_uexp(m, e); - [d, ...ds]; - }, - es, - Some([]), - ); + let+ ds = es |> List.map(dhexp_of_uexp(m)) |> OptUtil.sequence; DHExp.Tuple(ds); - | Tag(name) => Some(Tag(name)) | Cons(e1, e2) => let* dc1 = dhexp_of_uexp(m, e1); let+ dc2 = dhexp_of_uexp(m, e2); @@ -213,9 +212,15 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => DHExp.Ap(TestLit(id), dtest); | Var(name) => switch (err_status) { - | InHole(Free(Variable)) => Some(FreeVar(id, 0, name)) + | InHole(FreeVariable(_)) => Some(FreeVar(id, 0, name)) | _ => Some(BoundVar(name)) } + | Constructor(name) => + switch (err_status) { + | InHole(Common(NoType(FreeConstructor(_)))) => + Some(FreeVar(id, 0, name)) + | _ => Some(Constructor(name)) + } | Let(p, def, body) => let add_name: (option(string), DHExp.t) => DHExp.t = ( name => @@ -225,15 +230,15 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => ); let* dp = dhpat_of_upat(m, p); let* ddef = dhexp_of_uexp(m, def); - let+ dbody = dhexp_of_uexp(m, body); - let ty = Statics.pat_self_typ(m, p); + let* dbody = dhexp_of_uexp(m, body); + let+ ty_body = fixed_exp_typ(m, body); switch (Term.UPat.get_recursive_bindings(p)) { | None => /* not recursive */ DHExp.Let(dp, add_name(Term.UPat.get_var(p), ddef), dbody) | Some([f]) => /* simple recursion */ - Let(dp, FixF(f, ty, add_name(Some(f), ddef)), dbody) + Let(dp, FixF(f, ty_body, add_name(Some(f), ddef)), dbody) | Some(fs) => /* mutual recursion */ let ddef = @@ -255,7 +260,7 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => }, (0, ddef), ); - Let(dp, FixF(self_id, ty, substituted_def), dbody); + Let(dp, FixF(self_id, ty_body, substituted_def), dbody); }; | Ap(fn, arg) => let* c_fn = dhexp_of_uexp(m, fn); @@ -269,7 +274,7 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => DHExp.[Rule(BoolLit(true), d1), Rule(BoolLit(false), d2)]; let d = DHExp.Case(d_scrut, d_rules, 0); switch (err_status) { - | InHole(SynInconsistentBranches(_)) => + | InHole(Common(Inconsistent(Internal(_)))) => DHExp.InconsistentBranches(id, 0, d) | _ => ConsistentCase(d) }; @@ -287,20 +292,21 @@ let rec dhexp_of_uexp = (m: Statics.map, uexp: Term.UExp.t): option(DHExp.t) => |> OptUtil.sequence; let d = DHExp.Case(d_scrut, d_rules, 0); switch (err_status) { - | InHole(SynInconsistentBranches(_)) => + | InHole(Common(Inconsistent(Internal(_)))) => DHExp.InconsistentBranches(id, 0, d) | _ => ConsistentCase(d) }; + | TyAlias(_, _, e) => dhexp_of_uexp(m, e) }; - wrap(id, mode, self, d); - | Some(InfoPat(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) + wrap(ctx, id, mode, self, d); + | Some(InfoPat(_) | InfoTyp(_) | InfoTPat(_)) | None => None }; } -and dhpat_of_upat = (m: Statics.map, upat: Term.UPat.t): option(DHPat.t) => { +and dhpat_of_upat = (m: Statics.Map.t, upat: Term.UPat.t): option(DHPat.t) => { switch (Id.Map.find_opt(Term.UPat.rep_id(upat), m)) { - | Some(InfoPat({mode, self, _})) => - let err_status = Statics.error_status(mode, self); + | Some(InfoPat({mode, self, ctx, _})) => + let err_status = Info.status_pat(ctx, mode, self); let maybe_reason: option(ErrStatus.HoleReason.t) = switch (err_status) { | NotInHole(_) => None @@ -313,7 +319,7 @@ and dhpat_of_upat = (m: Statics.map, upat: Term.UPat.t): option(DHPat.t) => { | Some(reason) => Some(NonEmptyHole(reason, u, 0, d)) }; switch (upat.term) { - | Invalid(_) /* NOTE: treating invalid as a hole for now */ + | Invalid(t) => Some(DHPat.InvalidText(u, 0, t)) | EmptyHole => Some(EmptyHole(u, 0)) | MultiHole(_) => // TODO: dhexp, eval for multiholes @@ -326,30 +332,21 @@ and dhpat_of_upat = (m: Statics.map, upat: Term.UPat.t): option(DHPat.t) => { | Triv => wrap(Tuple([])) | ListLit(ps) => let* ds = ps |> List.map(dhpat_of_upat(m)) |> OptUtil.sequence; - let ty = Statics.pat_typ(m, upat) |> Typ.matched_list; - wrap(ListLit(ty, ds)); - | Tag(name) => wrap(Tag(name)) + let* ty = fixed_pat_typ(m, upat); + wrap(ListLit(Typ.matched_list(ty), ds)); + | Constructor(name) => + switch (err_status) { + | InHole(Common(NoType(FreeConstructor(_)))) => + Some(BadConstructor(u, 0, name)) + | _ => wrap(Constructor(name)) + } | Cons(hd, tl) => let* d_hd = dhpat_of_upat(m, hd); let* d_tl = dhpat_of_upat(m, tl); wrap(Cons(d_hd, d_tl)); | Tuple(ps) => - let dps = - List.fold_right( - (p, dps_opt) => { - switch (dps_opt) { - | None => None - | Some(dps) => - switch (dhpat_of_upat(m, p)) { - | None => None - | Some(dp) => Some([dp, ...dps]) - } - } - }, - ps, - Some([]), - ); - dps |> Option.map(ds => DHPat.Tuple(ds)); + let* ds = ps |> List.map(dhpat_of_upat(m)) |> OptUtil.sequence; + wrap(DHPat.Tuple(ds)); | Var(name) => Some(Var(name)) | Parens(p) => dhpat_of_upat(m, p) | Ap(p1, p2) => @@ -360,7 +357,7 @@ and dhpat_of_upat = (m: Statics.map, upat: Term.UPat.t): option(DHPat.t) => { let* dp = dhpat_of_upat(m, p); wrap(dp); }; - | Some(InfoExp(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) + | Some(InfoExp(_) | InfoTyp(_) | InfoTPat(_)) | None => None }; }; @@ -372,10 +369,17 @@ let uexp_elab_wrap_builtins = (d: DHExp.t): DHExp.t => Builtins.forms(Builtins.Pervasives.builtins), ); -let uexp_elab = (m: Statics.map, uexp: Term.UExp.t): ElaborationResult.t => +//let dhexp_of_uexp = Core.Memo.general(~cache_size_bound=1000, dhexp_of_uexp); + +let uexp_elab = (m: Statics.Map.t, uexp: Term.UExp.t): ElaborationResult.t => switch (dhexp_of_uexp(m, uexp)) { | None => DoesNotElaborate | Some(d) => let d = uexp_elab_wrap_builtins(d); - Elaborates(d, Typ.Unknown(Internal), Delta.empty); //TODO: get type from ci + let ty = + switch (fixed_exp_typ(m, uexp)) { + | Some(ty) => ty + | None => Typ.Unknown(Internal) + }; + Elaborates(d, ty, Delta.empty); }; diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 58d567e942..647740eeb3 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -19,15 +19,24 @@ type match_result = | DoesNotMatch | IndetMatch; +let const_unknown: 'a => Typ.t = _ => Unknown(Internal); + let grounded_Arrow = NotGroundOrHole(Arrow(Unknown(Internal), Unknown(Internal))); -let grounded_Sum = - NotGroundOrHole(Sum(Unknown(Internal), Unknown(Internal))); let grounded_Prod = length => NotGroundOrHole(Prod(ListUtil.replicate(length, Typ.Unknown(Internal)))); +let grounded_Sum = (sm: Typ.sum_map): ground_cases => { + let sm' = sm |> ConstructorMap.map(Option.map(const_unknown)); + NotGroundOrHole(Sum(sm')); +}; let grounded_List = NotGroundOrHole(List(Unknown(Internal))); -let ground_cases_of = (ty: Typ.t): ground_cases => +let rec ground_cases_of = (ty: Typ.t): ground_cases => { + let is_ground_arg: option(Typ.t) => bool = + fun + | None + | Some(Typ.Unknown(_)) => true + | Some(ty) => ground_cases_of(ty) == Ground; switch (ty) { | Unknown(_) => Hole | Bool @@ -35,8 +44,8 @@ let ground_cases_of = (ty: Typ.t): ground_cases => | Float | String | Var(_) + | Rec(_) | Arrow(Unknown(_), Unknown(_)) - | Sum(Unknown(_), Unknown(_)) | List(Unknown(_)) => Ground | Prod(tys) => if (List.for_all( @@ -49,10 +58,33 @@ let ground_cases_of = (ty: Typ.t): ground_cases => } else { tys |> List.length |> grounded_Prod; } + | Sum(sm) => + sm |> ConstructorMap.is_ground(is_ground_arg) ? Ground : grounded_Sum(sm) | Arrow(_, _) => grounded_Arrow - | Sum(_, _) => grounded_Sum | List(_) => grounded_List }; +}; + +let cast_sum_maps = + (sm1: Typ.sum_map, sm2: Typ.sum_map) + : option(ConstructorMap.t((Typ.t, Typ.t))) => { + let (ctrs1, tys1) = sm1 |> ConstructorMap.bindings |> List.split; + let (ctrs2, tys2) = sm2 |> ConstructorMap.bindings |> List.split; + if (ctrs1 == ctrs2) { + let tys1 = tys1 |> List.filter(Option.is_some) |> List.map(Option.get); + let tys2 = tys2 |> List.filter(Option.is_some) |> List.map(Option.get); + if (List.length(tys1) == List.length(tys2)) { + Some( + List.(combine(tys1, tys2) |> combine(ctrs1)) + |> ConstructorMap.of_list, + ); + } else { + None; + }; + } else { + None; + }; +}; let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => switch (dp, d) { @@ -62,6 +94,7 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | (Wild, _) => Matches(Environment.empty) | (ExpandingKeyword(_), _) => DoesNotMatch | (InvalidText(_), _) => IndetMatch + | (BadConstructor(_), _) => IndetMatch | (Var(x), _) => let env = Environment.extend(Environment.empty, (x, d)); Matches(env); @@ -118,23 +151,53 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | (StringLit(_), Cast(d, String, Unknown(_))) => matches(dp, d) | (StringLit(_), Cast(d, Unknown(_), String)) => matches(dp, d) | (StringLit(_), _) => DoesNotMatch - | (Tag(n1), Tag(n2)) => - if (n1 == n2) { - Matches(Environment.empty); - } else { - DoesNotMatch; + + | (Ap(dp1, dp2), Ap(d1, d2)) => + switch (matches(dp1, d1)) { + | DoesNotMatch => DoesNotMatch + | IndetMatch => + switch (matches(dp2, d2)) { + | DoesNotMatch => DoesNotMatch + | IndetMatch + | Matches(_) => IndetMatch + } + | Matches(env1) => + switch (matches(dp2, d2)) { + | DoesNotMatch => DoesNotMatch + | IndetMatch => IndetMatch + | Matches(env2) => Matches(Environment.union(env1, env2)) + } } - | (Tag(_), Cast(d, _, Unknown(_))) => matches(dp, d) - | (Tag(_), Cast(d, Unknown(_), _)) => matches(dp, d) - | (Tag(_), _) => DoesNotMatch - | (Inj(side1, dp), Inj(_, side2, d)) => - switch (side1, side2) { - | (L, L) - | (R, R) => matches(dp, d) - | _ => DoesNotMatch + | ( + Ap(Constructor(ctr), dp_opt), + Cast(d, Sum(sm1) | Rec(_, Sum(sm1)), Sum(sm2) | Rec(_, Sum(sm2))), + ) => + switch (cast_sum_maps(sm1, sm2)) { + | Some(castmap) => matches_cast_Sum(ctr, Some(dp_opt), d, [castmap]) + | None => DoesNotMatch } - | (Inj(side, dp), Cast(_)) => matches_cast_Inj(side, dp, d, []) - | (Inj(_, _), _) => DoesNotMatch + + | (Ap(_, _), Cast(d, Sum(_) | Rec(_, Sum(_)), Unknown(_))) + | (Ap(_, _), Cast(d, Unknown(_), Sum(_) | Rec(_, Sum(_)))) => + matches(dp, d) + | (Ap(_, _), _) => DoesNotMatch + + | (Constructor(ctr), Constructor(ctr')) => + ctr == ctr' ? Matches(Environment.empty) : DoesNotMatch + | ( + Constructor(ctr), + Cast(d, Sum(sm1) | Rec(_, Sum(sm1)), Sum(sm2) | Rec(_, Sum(sm2))), + ) => + switch (cast_sum_maps(sm1, sm2)) { + | Some(castmap) => matches_cast_Sum(ctr, None, d, [castmap]) + | None => DoesNotMatch + } + | (Constructor(_), Cast(d, Sum(_) | Rec(_, Sum(_)), Unknown(_))) => + matches(dp, d) + | (Constructor(_), Cast(d, Unknown(_), Sum(_) | Rec(_, Sum(_)))) => + matches(dp, d) + | (Constructor(_), _) => DoesNotMatch + | (Tuple(dps), Tuple(ds)) => if (List.length(dps) != List.length(ds)) { DoesNotMatch; @@ -156,22 +219,6 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => ds, ); } - | (Ap(dp1, dp2), Ap(d1, d2)) => - switch (matches(dp1, d1)) { - | DoesNotMatch => DoesNotMatch - | IndetMatch => - switch (matches(dp2, d2)) { - | DoesNotMatch => DoesNotMatch - | IndetMatch - | Matches(_) => IndetMatch - } - | Matches(env1) => - switch (matches(dp2, d2)) { - | DoesNotMatch => DoesNotMatch - | IndetMatch => IndetMatch - | Matches(env2) => Matches(Environment.union(env1, env2)) - } - } | (Tuple(dps), Cast(d, Prod(tys), Prod(tys'))) => assert(List.length(tys) == List.length(tys')); matches_cast_Tuple( @@ -185,10 +232,7 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => d, List.map( p => [p], - List.combine( - tys, - List.init(List.length(tys), _ => Typ.Unknown(Internal)), - ), + List.combine(tys, List.init(List.length(tys), const_unknown)), ), ) | (Tuple(dps), Cast(d, Unknown(_), Prod(tys'))) => @@ -197,10 +241,7 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => d, List.map( p => [p], - List.combine( - List.init(List.length(tys'), _ => Typ.Unknown(Internal)), - tys', - ), + List.combine(List.init(List.length(tys'), const_unknown), tys'), ), ) | (Tuple(_), Cast(_)) => DoesNotMatch @@ -216,84 +257,73 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | (Cons(_, _), ListLit(_)) | (ListLit(_), ListLit(_)) => matches_cast_Cons(dp, d, []) | (Cons(_) | ListLit(_), _) => DoesNotMatch - | (Ap(_, _), _) => DoesNotMatch } -and matches_cast_Inj = +and matches_cast_Sum = ( - side: InjSide.t, - dp: DHPat.t, + ctr: string, + dp: option(DHPat.t), d: DHExp.t, - casts: list((Typ.t, Typ.t, Typ.t, Typ.t)), + castmaps: list(ConstructorMap.t((Typ.t, Typ.t))), ) : match_result => switch (d) { - | Inj(_, side', d') => - switch (side, side') { - | (L, L) - | (R, R) => - let side_casts = - List.map( - (c: (Typ.t, Typ.t, Typ.t, Typ.t)) => { - let (tyL1, tyR1, tyL2, tyR2) = c; - switch (side) { - | L => (tyL1, tyL2) - | R => (tyR1, tyR2) - }; - }, - casts, - ); - matches(dp, DHExp.apply_casts(d', side_casts)); + | Constructor(ctr') => + switch ( + dp, + castmaps |> List.map(ConstructorMap.find_opt(ctr')) |> OptUtil.sequence, + ) { + | (None, Some(_)) => + ctr == ctr' ? Matches(Environment.empty) : DoesNotMatch | _ => DoesNotMatch } - | Cast(d', Sum(tyL1, tyR1), Sum(tyL2, tyR2)) => - matches_cast_Inj(side, dp, d', [(tyL1, tyR1, tyL2, tyR2), ...casts]) - | Cast(d', Sum(tyL1, tyR1), Unknown(_)) => - matches_cast_Inj( - side, - dp, - d', - [(tyL1, tyR1, Unknown(Internal), Unknown(Internal))], - ) - | Cast(d', Unknown(_), Sum(tyL2, tyR2)) => - matches_cast_Inj( - side, + | Ap(Constructor(ctr'), d') => + switch ( dp, - d', - [(Unknown(Internal), Unknown(Internal), tyL2, tyR2)], - ) - | Cast(_, _, _) => DoesNotMatch - | BoundVar(_) => DoesNotMatch - | FreeVar(_) => IndetMatch - | InvalidText(_) => IndetMatch - | ExpandingKeyword(_) => IndetMatch - | Let(_, _, _) => IndetMatch - | FixF(_, _, _) => DoesNotMatch - | Fun(_, _, _, _) => DoesNotMatch - | Closure(_, Fun(_)) => DoesNotMatch - | Closure(_, _) => IndetMatch - | Ap(_, _) => IndetMatch - | ApBuiltin(_, _) => IndetMatch - | BinBoolOp(_, _, _) - | BinIntOp(_, _, _) - | BinFloatOp(_, _, _) - | BinStringOp(_, _, _) - | BoolLit(_) => DoesNotMatch - | IntLit(_) => DoesNotMatch - | Sequence(_) - | TestLit(_) => DoesNotMatch - | FloatLit(_) => DoesNotMatch - | StringLit(_) => DoesNotMatch - | ListLit(_, _, _, _, _) => DoesNotMatch - | Cons(_, _) => DoesNotMatch - | Tuple(_) => DoesNotMatch - | Prj(_) => DoesNotMatch - | Tag(_) => DoesNotMatch - | ConsistentCase(_) - | InconsistentBranches(_) => IndetMatch - | EmptyHole(_) => IndetMatch - | NonEmptyHole(_) => IndetMatch - | FailedCast(_, _, _) => IndetMatch + castmaps |> List.map(ConstructorMap.find_opt(ctr')) |> OptUtil.sequence, + ) { + | (Some(dp), Some(side_casts)) => + matches(dp, DHExp.apply_casts(d', side_casts)) + | _ => DoesNotMatch + } + | Cast(d', Sum(sm1) | Rec(_, Sum(sm1)), Sum(sm2) | Rec(_, Sum(sm2))) => + switch (cast_sum_maps(sm1, sm2)) { + | Some(castmap) => matches_cast_Sum(ctr, dp, d', [castmap, ...castmaps]) + | None => DoesNotMatch + } + | Cast(d', Sum(_) | Rec(_, Sum(_)), Unknown(_)) + | Cast(d', Unknown(_), Sum(_) | Rec(_, Sum(_))) => + matches_cast_Sum(ctr, dp, d', castmaps) + | FreeVar(_) + | ExpandingKeyword(_) + | InvalidText(_) + | Let(_) + | Ap(_) + | ApBuiltin(_) + | BinBoolOp(_) + | BinIntOp(_) + | BinFloatOp(_) + | BinStringOp(_) + | InconsistentBranches(_) + | EmptyHole(_) + | NonEmptyHole(_) + | FailedCast(_, _, _) | InvalidOperation(_) => IndetMatch + | Cast(_) + | BoundVar(_) + | FixF(_) + | Fun(_) + | BoolLit(_) + | IntLit(_) + | FloatLit(_) + | StringLit(_) + | ListLit(_) + | Tuple(_) + | Prj(_) + | ConsistentCase(_) + | Sequence(_, _) + | Closure(_) + | TestLit(_) + | Cons(_) => DoesNotMatch } and matches_cast_Tuple = ( @@ -337,14 +367,14 @@ and matches_cast_Tuple = ); } | Cast(d', Prod(tys), Unknown(_)) => - let tys' = List.init(List.length(tys), _ => Typ.Unknown(Internal)); + let tys' = List.init(List.length(tys), const_unknown); matches_cast_Tuple( dps, d', List.map2(List.cons, List.combine(tys, tys'), elt_casts), ); | Cast(d', Unknown(_), Prod(tys')) => - let tys = List.init(List.length(tys'), _ => Typ.Unknown(Internal)); + let tys = List.init(List.length(tys'), const_unknown); matches_cast_Tuple( dps, d', @@ -372,11 +402,10 @@ and matches_cast_Tuple = | TestLit(_) => DoesNotMatch | FloatLit(_) => DoesNotMatch | StringLit(_) => DoesNotMatch - | Inj(_, _, _) => DoesNotMatch | ListLit(_) => DoesNotMatch | Cons(_, _) => DoesNotMatch | Prj(_) => DoesNotMatch - | Tag(_) => DoesNotMatch + | Constructor(_) => DoesNotMatch | ConsistentCase(_) | InconsistentBranches(_) => IndetMatch | EmptyHole(_) => IndetMatch @@ -387,12 +416,12 @@ and matches_cast_Tuple = and matches_cast_Cons = (dp: DHPat.t, d: DHExp.t, elt_casts: list((Typ.t, Typ.t))): match_result => switch (d) { - | ListLit(_, _, _, _, []) => + | ListLit(_, _, _, []) => switch (dp) { | ListLit(_, []) => Matches(Environment.empty) | _ => DoesNotMatch } - | ListLit(u, i, err, ty, [dhd, ...dtl] as ds) => + | ListLit(u, i, ty, [dhd, ...dtl] as ds) => switch (dp) { | Cons(dp1, dp2) => switch (matches(dp1, DHExp.apply_casts(dhd, elt_casts))) { @@ -407,7 +436,7 @@ and matches_cast_Cons = }, elt_casts, ); - let d2 = DHExp.ListLit(u, i, err, ty, dtl); + let d2 = DHExp.ListLit(u, i, ty, dtl); switch (matches(dp2, DHExp.apply_casts(d2, list_casts))) { | DoesNotMatch => DoesNotMatch | IndetMatch => IndetMatch @@ -508,10 +537,9 @@ and matches_cast_Cons = | TestLit(_) => DoesNotMatch | FloatLit(_) => DoesNotMatch | StringLit(_) => DoesNotMatch - | Inj(_, _, _) => DoesNotMatch | Tuple(_) => DoesNotMatch | Prj(_) => DoesNotMatch - | Tag(_) => DoesNotMatch + | Constructor(_) => DoesNotMatch | ConsistentCase(_) | InconsistentBranches(_) => IndetMatch | EmptyHole(_) => IndetMatch @@ -641,7 +669,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = let* r1 = evaluate(env, d1); switch (r1) { | BoxedValue(TestLit(id)) => evaluate_test(env, id, d2) - | BoxedValue(Tag(_)) => + | BoxedValue(Constructor(_)) => let* r2 = evaluate(env, d2); switch (r2) { | BoxedValue(d2) => BoxedValue(Ap(d1, d2)) |> return @@ -689,7 +717,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | IntLit(_) | FloatLit(_) | StringLit(_) - | Tag(_) => BoxedValue(d) |> return + | Constructor(_) => BoxedValue(d) |> return | BinBoolOp(op, d1, d2) => let* r1 = evaluate(env, d1); @@ -809,13 +837,6 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = }; }; - | Inj(ty, side, d1) => - let* r1 = evaluate(env, d1); - switch (r1) { - | BoxedValue(d1') => BoxedValue(Inj(ty, side, d1')) |> return - | Indet(d1') => Indet(Inj(ty, side, d1')) |> return - }; - | Tuple(ds) => let+ lst = ds |> List.map(evaluate(env)) |> sequence; let (ds', indet) = @@ -892,8 +913,8 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | (BoxedValue(d1), Indet(d2)) => Indet(Cons(d1, d2)) |> return | (BoxedValue(d1), BoxedValue(d2)) => switch (d2) { - | ListLit(u, i, err, ty, ds) => - BoxedValue(ListLit(u, i, err, ty, [d1, ...ds])) |> return + | ListLit(u, i, ty, ds) => + BoxedValue(ListLit(u, i, ty, [d1, ...ds])) |> return | Cons(_) | Cast(_, List(_), List(_)) => BoxedValue(Cons(d1, d2)) |> return | _ => @@ -902,7 +923,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = } }; - | ListLit(u, i, err, ty, lst) => + | ListLit(u, i, ty, lst) => let+ lst = lst |> List.map(evaluate(env)) |> sequence; let (lst, indet) = List.fold_right( @@ -914,7 +935,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = lst, ([], false), ); - let d = DHExp.ListLit(u, i, err, ty, lst); + let d = DHExp.ListLit(u, i, ty, lst); if (indet) { Indet(d); } else { @@ -1160,6 +1181,14 @@ and evaluate_test = let mk_op = (arg_d1, arg_d2) => DHExp.BinFloatOp(op, arg_d1, arg_d2); evaluate_test_eq(env, mk_op, arg_d1, arg_d2); + | Ap(fn, Tuple(args)) => + let* args_d: list(EvaluatorResult.t) = + args |> List.map(evaluate(env)) |> sequence; + let arg_show = + DHExp.Ap(fn, Tuple(List.map(EvaluatorResult.unbox, args_d))); + let* arg_result = evaluate(env, arg_show); + (arg_show, arg_result) |> return; + | Ap(Ap(arg_d1, arg_d2), arg_d3) => let* arg_d1 = evaluate(env, arg_d1); let* arg_d2 = evaluate(env, arg_d2); diff --git a/src/haz3lcore/dynamics/EvaluatorPost.re b/src/haz3lcore/dynamics/EvaluatorPost.re index ef37e2a44a..03dd0d2a71 100644 --- a/src/haz3lcore/dynamics/EvaluatorPost.re +++ b/src/haz3lcore/dynamics/EvaluatorPost.re @@ -58,7 +58,7 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => | IntLit(_) | FloatLit(_) | StringLit(_) - | Tag(_) => d |> return + | Constructor(_) => d |> return | Sequence(d1, d2) => let* d1' = pp_eval(d1); @@ -99,7 +99,7 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => let* d2' = pp_eval(d2); Cons(d1', d2') |> return; - | ListLit(a, b, c, d, ds) => + | ListLit(a, b, c, ds) => let+ ds = ds |> List.fold_left( @@ -110,11 +110,7 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => }, return([]), ); - ListLit(a, b, c, d, ds); - - | Inj(ty, side, d') => - let* d'' = pp_eval(d'); - Inj(ty, side, d'') |> return; + ListLit(a, b, c, ds); | Tuple(ds) => let+ ds = @@ -271,7 +267,7 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => | IntLit(_) | FloatLit(_) | StringLit(_) - | Tag(_) => d |> return + | Constructor(_) => d |> return | Sequence(d1, d2) => let* d1' = pp_uneval(env, d1); @@ -324,7 +320,7 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => let* d2' = pp_uneval(env, d2); Cons(d1', d2') |> return; - | ListLit(a, b, c, d, ds) => + | ListLit(a, b, c, ds) => let+ ds = ds |> List.fold_left( @@ -335,11 +331,7 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => }, return([]), ); - ListLit(a, b, c, d, ds); - - | Inj(ty, side, d') => - let* d'' = pp_uneval(env, d'); - Inj(ty, side, d'') |> return; + ListLit(a, b, c, ds); | Tuple(ds) => let+ ds = @@ -438,7 +430,7 @@ let rec track_children_of_hole = (hii: HoleInstanceInfo.t, parent: HoleInstanceParents.t_, d: DHExp.t) : HoleInstanceInfo.t => switch (d) { - | Tag(_) + | Constructor(_) | TestLit(_) | BoolLit(_) | IntLit(_) @@ -447,7 +439,6 @@ let rec track_children_of_hole = | BoundVar(_) => hii | FixF(_, _, d) | Fun(_, _, d, _) - | Inj(_, _, d) | Prj(d, _) | Cast(d, _, _) | FailedCast(d, _, _) @@ -463,7 +454,7 @@ let rec track_children_of_hole = let hii = track_children_of_hole(hii, parent, d1); track_children_of_hole(hii, parent, d2); - | ListLit(_, _, _, _, ds) => + | ListLit(_, _, _, ds) => List.fold_right( (d, hii) => track_children_of_hole(hii, parent, d), ds, diff --git a/src/haz3lcore/dynamics/HTyp.re b/src/haz3lcore/dynamics/HTyp.re deleted file mode 100644 index 435400a9bc..0000000000 --- a/src/haz3lcore/dynamics/HTyp.re +++ /dev/null @@ -1,190 +0,0 @@ -open Sexplib.Std; -open Util; - -/* types with holes */ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Hole - | Int - | Float - | Bool - | String - | Arrow(t, t) - | Sum(t, t) - | Prod(list(t)) - | List(t); - -[@deriving sexp] -type join = - | GLB - | LUB; - -let precedence_Prod = 1; -let precedence_Arrow = 2; -let precedence_Sum = 3; -let precedence_const = 4; -let precedence = (ty: t): int => - switch (ty) { - | Int - | Float - | String - | Bool - | Hole - | Prod([]) - | List(_) => precedence_const - | Prod(_) => precedence_Prod - | Sum(_, _) => precedence_Sum - | Arrow(_, _) => precedence_Arrow - }; - -/* equality - At the moment, this coincides with default equality, - but this will change when polymorphic types are implemented */ -let eq = (==); - -/* type consistency */ -let rec consistent = (x, y) => - switch (x, y) { - | (Hole, _) - | (_, Hole) => true - | (Int, Int) => true - | (Int, _) => false - | (Float, Float) => true - | (Float, _) => false - | (Bool, Bool) => true - | (Bool, _) => false - | (String, String) => true - | (String, _) => false - | (Arrow(ty1, ty2), Arrow(ty1', ty2')) - | (Sum(ty1, ty2), Sum(ty1', ty2')) => - consistent(ty1, ty1') && consistent(ty2, ty2') - | (Arrow(_, _), _) => false - | (Sum(_, _), _) => false - | (Prod(tys1), Prod(tys2)) => - ListUtil.for_all2_opt(consistent, tys1, tys2) - |> Option.value(~default=false) - | (Prod(_), _) => false - | (List(ty), List(ty')) => consistent(ty, ty') - | (List(_), _) => false - }; - -let inconsistent = (ty1, ty2) => !consistent(ty1, ty2); - -let rec consistent_all = (types: list(t)): bool => - switch (types) { - | [] => true - | [hd, ...tl] => - if (List.exists(inconsistent(hd), tl)) { - false; - } else { - consistent_all(tl); - } - }; - -/* matched arrow types */ -let matched_arrow = - fun - | Hole => Some((Hole, Hole)) - | Arrow(ty1, ty2) => Some((ty1, ty2)) - | _ => None; - -let get_prod_elements: t => list(t) = - fun - | Prod(tys) => tys - | _ as ty => [ty]; - -let get_prod_arity = ty => ty |> get_prod_elements |> List.length; - -/* matched sum types */ -let matched_sum = - fun - | Hole => Some((Hole, Hole)) - | Sum(tyL, tyR) => Some((tyL, tyR)) - | _ => None; - -/* matched list types */ -let matched_list = - fun - | Hole => Some(Hole) - | List(ty) => Some(ty) - | _ => None; - -/* complete (i.e. does not have any holes) */ -let rec complete = - fun - | Hole => false - | Int => true - | Float => true - | Bool => true - | String => true - | Arrow(ty1, ty2) - | Sum(ty1, ty2) => complete(ty1) && complete(ty2) - | Prod(tys) => tys |> List.for_all(complete) - | List(ty) => complete(ty); - -let rec join = (j, ty1, ty2) => - switch (ty1, ty2) { - | (_, Hole) => - switch (j) { - | GLB => Some(Hole) - | LUB => Some(ty1) - } - | (Hole, _) => - switch (j) { - | GLB => Some(Hole) - | LUB => Some(ty2) - } - | (Int, Int) => Some(ty1) - | (Int, _) => None - | (Float, Float) => Some(ty1) - | (Float, _) => None - | (Bool, Bool) => Some(ty1) - | (Bool, _) => None - | (String, String) => Some(ty1) - | (String, _) => None - | (Arrow(ty1, ty2), Arrow(ty1', ty2')) => - switch (join(j, ty1, ty1'), join(j, ty2, ty2')) { - | (Some(ty1), Some(ty2)) => Some(Arrow(ty1, ty2)) - | _ => None - } - | (Arrow(_), _) => None - | (Sum(ty1, ty2), Sum(ty1', ty2')) => - switch (join(j, ty1, ty1'), join(j, ty2, ty2')) { - | (Some(ty1), Some(ty2)) => Some(Sum(ty1, ty2)) - | _ => None - } - | (Sum(_), _) => None - | (Prod(tys1), Prod(tys2)) => - ListUtil.map2_opt(join(j), tys1, tys2) - |> Option.map(OptUtil.sequence) - |> Option.join - |> Option.map(joined_types => Prod(joined_types)) - | (Prod(_), _) => None - | (List(ty), List(ty')) => - switch (join(j, ty, ty')) { - | Some(ty) => Some(List(ty)) - | None => None - } - | (List(_), _) => None - }; - -let join_all = (j: join, types: list(t)): option(t) => { - switch (types) { - | [] => None - | [hd] => Some(hd) - | [hd, ...tl] => - if (!consistent_all(types)) { - None; - } else { - List.fold_left( - (common_opt, ty) => - switch (common_opt) { - | None => None - | Some(common_ty) => join(j, common_ty, ty) - }, - Some(hd), - tl, - ); - } - }; -}; diff --git a/src/haz3lcore/dynamics/HTyp.rei b/src/haz3lcore/dynamics/HTyp.rei deleted file mode 100644 index 069d5f843a..0000000000 --- a/src/haz3lcore/dynamics/HTyp.rei +++ /dev/null @@ -1,39 +0,0 @@ -/* types with holes */ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Hole - | Int - | Float - | Bool - | String - | Arrow(t, t) - | Sum(t, t) - | Prod(list(t)) - | List(t); - -type join = - | GLB - | LUB; - -let precedence_Prod: int; -let precedence_Arrow: int; -let precedence_Sum: int; -let precedence: t => int; - -/* type equality */ -let eq: (t, t) => bool; - -/* type consistency */ -let consistent: (t, t) => bool; - -let get_prod_elements: t => list(t); -let get_prod_arity: t => int; - -let matched_arrow: t => option((t, t)); -let matched_sum: t => option((t, t)); -let matched_list: t => option(t); - -let complete: t => bool; - -let join: (join, t, t) => option(t); -let join_all: (join, list(t)) => option(t); diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index 3d8a037c05..e4287b56e6 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -3,6 +3,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel + | InvalidIntOfString + | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -10,5 +12,7 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" + | InvalidIntOfString => "Error: Invalid String to Int Conversion" + | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; diff --git a/src/haz3lcore/dynamics/InvalidOperationError.rei b/src/haz3lcore/dynamics/InvalidOperationError.rei index b7338619be..b255c1f95d 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.rei +++ b/src/haz3lcore/dynamics/InvalidOperationError.rei @@ -3,6 +3,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel + | InvalidIntOfString + | InvalidFloatOfString | InvalidProjection; let err_msg: t => string; diff --git a/src/haz3lcore/dynamics/ListErrStatus.re b/src/haz3lcore/dynamics/ListErrStatus.re deleted file mode 100644 index 6a6dba95fc..0000000000 --- a/src/haz3lcore/dynamics/ListErrStatus.re +++ /dev/null @@ -1,6 +0,0 @@ -open Sexplib.Std; - -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | StandardErrStatus(ErrStatus.t) - | InconsistentBranches(list(Typ.t), MetaVar.t); diff --git a/src/haz3lcore/dynamics/Substitution.re b/src/haz3lcore/dynamics/Substitution.re index d392c14cdc..70120469a2 100644 --- a/src/haz3lcore/dynamics/Substitution.re +++ b/src/haz3lcore/dynamics/Substitution.re @@ -56,9 +56,9 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => | IntLit(_) | FloatLit(_) | StringLit(_) - | Tag(_) => d2 - | ListLit(a, b, c, d, ds) => - ListLit(a, b, c, d, List.map(subst_var(d1, x), ds)) + | Constructor(_) => d2 + | ListLit(a, b, c, ds) => + ListLit(a, b, c, List.map(subst_var(d1, x), ds)) | Cons(d3, d4) => let d3 = subst_var(d1, x, d3); let d4 = subst_var(d1, x, d4); @@ -81,9 +81,6 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => let d3 = subst_var(d1, x, d3); let d4 = subst_var(d1, x, d4); BinStringOp(op, d3, d4); - | Inj(ty, side, d3) => - let d3 = subst_var(d1, x, d3); - Inj(ty, side, d3); | ConsistentCase(Case(d3, rules, n)) => let d3 = subst_var(d1, x, d3); let rules = subst_var_rules(d1, x, rules); diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index 9cd2566613..dd5050e632 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -45,6 +45,11 @@ type t = { mold: Mold.t, }; +[@deriving (show({with_path: false}), sexp, yojson)] +type bad_token_cls = + | Other + | BadInt; + let mk = (expansion, label, mold) => {label, mold, expansion}; /* Abbreviations for expansion behaviors */ @@ -62,8 +67,9 @@ let mk_nul_infix = (t: Token.t, prec) => mk(ss, [t], mk_bin(~l=Any, ~r=Any, prec, Any, [])); /* Token Recognition Predicates */ -let is_arbitary_int = regexp("^[0-9_]*$"); -let is_arbitary_float = x => x != "." && regexp("^[0-9]*\\.[0-9]*$", x); +let is_arbitary_int = regexp("^-?\\d+[0-9_]*$"); +let is_arbitary_float = x => + x != "." && regexp("^-?[0-9]*\\.?[0-9]*((e|E)-?[0-9]*)?$", x); let is_int = str => is_arbitary_int(str) && int_of_string_opt(str) != None; /* NOTE: The is_arbitary_int check is necessary to prevent minuses from being parsed as part of the int token. */ @@ -83,18 +89,16 @@ let is_bool = str => str == "true" || str == "false"; let is_reserved = str => is_bool(str); let is_var = str => !is_reserved(str) && regexp("^[a-z][A-Za-z0-9_]*$", str); let is_capitalized_name = regexp("^[A-Z][A-Za-z0-9_]*$"); -let is_tag = is_capitalized_name; -let is_concrete_typ = str => - str == "String" || str == "Int" || str == "Float" || str == "Bool"; -let is_typ_var = t => is_capitalized_name(t) && !is_concrete_typ(t); -let is_partial_concrete_typ = x => - !is_concrete_typ(x) && is_capitalized_name(x); +let is_ctr = is_capitalized_name; +let is_base_typ = regexp("^(String|Int|Float|Bool)$"); +let is_typ_var = is_capitalized_name; +let is_partial_base_typ = x => !is_base_typ(x) && is_capitalized_name(x); let is_wild = regexp("^_$"); /* The below case represents tokens which we want the user to be able to type in, but which have no reasonable semantic interpretation */ let is_bad_lit = str => - is_bad_int(str) || is_bad_float(str) || is_partial_concrete_typ(str); + is_bad_int(str) || is_bad_float(str) || is_partial_base_typ(str); /* is_string: last clause is a somewhat hacky way of making sure there are at most two quotes, in order to prevent merges */ @@ -141,7 +145,7 @@ let duomerges = (lbl: Label.t): option(Label.t) => exceptions when used elsewhere, as no molds will be found. Such exceptions are currently caught. This should be replaced by a more disciplined approach to invalid text.*/ -let is_whitelisted_char = regexp("[!@]"); +let is_whitelisted_char = regexp("[!@\\{\\}]"); /* A. Secondary Notation (Comments, Whitespace, etc.) */ let space = " "; @@ -155,6 +159,13 @@ let is_comment_delim = t => t == "#"; let is_secondary = t => List.mem(t, [space, linebreak]) || regexp(comment_regexp, t); +let bad_token_cls: string => bad_token_cls = + t => + switch () { + | _ when is_bad_int(t) => BadInt + | _ => Other + }; + /* B. Operands: Order in this list determines relative remolding priority for forms with overlapping regexps */ @@ -162,8 +173,9 @@ let atomic_forms: list((string, (string => bool, list(Mold.t)))) = [ ("bad_lit", (is_bad_lit, [mk_op(Any, [])])), ("var", (is_var, [mk_op(Exp, []), mk_op(Pat, [])])), ("ty_var", (is_typ_var, [mk_op(Typ, [])])), - ("ctr", (is_tag, [mk_op(Exp, []), mk_op(Pat, [])])), - ("type", (is_concrete_typ, [mk_op(Typ, [])])), + ("ty_var_p", (is_typ_var, [mk_op(TPat, [])])), + ("ctr", (is_ctr, [mk_op(Exp, []), mk_op(Pat, [])])), + ("type", (is_base_typ, [mk_op(Typ, [])])), ("empty_list", (is_empty_list, [mk_op(Exp, []), mk_op(Pat, [])])), ( "empty_tuple", @@ -181,6 +193,8 @@ let atomic_forms: list((string, (string => bool, list(Mold.t)))) = [ priority for forms which share the same labels */ let forms: list((string, t)) = [ + ("typ_plus", mk_infix("+", Typ, P.or_)), + ("typ_sum_single", mk(ss, ["+"], mk_pre(P.or_, Typ, []))), ("cell-join", mk_infix(";", Exp, 10)), ("plus", mk_infix("+", Exp, P.plus)), ("minus", mk_infix("-", Exp, P.plus)), @@ -226,7 +240,12 @@ let forms: list((string, t)) = [ ("if_", mk(ds, ["if", "then", "else"], mk_pre(P.if_, Exp, [Exp, Exp]))), ("ap_exp", mk(ii, ["(", ")"], mk_post(P.ap, Exp, [Exp]))), ("ap_pat", mk(ii, ["(", ")"], mk_post(P.ap, Pat, [Pat]))), + ("ap_typ", mk(ii, ["(", ")"], mk_post(P.ap, Typ, [Typ]))), ("let_", mk(ds, ["let", "=", "in"], mk_pre(P.let_, Exp, [Pat, Exp]))), + ( + "type_alias", + mk(ds, ["type", "=", "in"], mk_pre(P.let_, Exp, [TPat, Typ])), + ), ("typeann", mk(ss, [":"], mk_bin'(P.ann, Pat, Pat, [], Typ))), ("case", mk(ds, ["case", "end"], mk_op(Exp, [Rul]))), ( @@ -260,7 +279,8 @@ let forms: list((string, t)) = [ //("block", mk(ii, ["{", "}"], mk_op(Exp, [Exp]))), ]; -let get: String.t => t = name => List.assoc(name, forms); +let get: String.t => t = + name => Util.ListUtil.assoc_err(name, forms, "Forms.get"); let delims: list(Token.t) = forms diff --git a/src/haz3lcore/lang/Sort.re b/src/haz3lcore/lang/Sort.re index 3ba8c327b2..2b66c3282b 100644 --- a/src/haz3lcore/lang/Sort.re +++ b/src/haz3lcore/lang/Sort.re @@ -4,12 +4,13 @@ type t = | Nul | Pat | Typ + | TPat | Rul | Exp; let root = Exp; -let all = [Any, Nul, Pat, Typ, Rul, Exp]; +let all = [Any, Nul, Pat, Typ, Rul, Exp, TPat]; let consistent = (s, s') => switch (s, s') { @@ -25,6 +26,17 @@ let to_string = | Any => "Any" | Nul => "Nul" | Pat => "Pat" + | TPat => "TPat" | Typ => "Typ" | Rul => "Rul" | Exp => "Exp"; + +let to_string_verbose = + fun + | Any => "any" + | Nul => "null" + | Pat => "pattern" + | TPat => "type pattern" + | Typ => "type" + | Rul => "rule" + | Exp => "expression"; diff --git a/src/haz3lcore/statics/BuiltinADTs.re b/src/haz3lcore/statics/BuiltinADTs.re deleted file mode 100644 index f8ed37f489..0000000000 --- a/src/haz3lcore/statics/BuiltinADTs.re +++ /dev/null @@ -1,97 +0,0 @@ -open Sexplib.Std; - -[@deriving (show({with_path: false}), sexp, yojson)] -type tag = { - name: string, - arg: option(Typ.t), -}; - -[@deriving (show({with_path: false}), sexp, yojson)] -type adt = (string, list(tag)); - -let alftyp = Typ.Var("ALFTyp"); -let alfexpr = Typ.Var("ALFExpr"); -let option_alftyp = Typ.Var("Option_ALFTyp"); - -let adts: list(adt) = [ - ( - "Color", - [ - {name: "Red", arg: None}, - {name: "Green", arg: None}, - {name: "Blue", arg: None}, - ], - ), - ( - "Option_ALFTyp", - [{name: "None", arg: None}, {name: "Some", arg: Some(alftyp)}], - ), - ( - "ALFTyp", - { - [ - {name: "Num", arg: None}, - {name: "Bool", arg: None}, - {name: "Arrow", arg: Some(Prod([alftyp, alftyp]))}, - {name: "Prod", arg: Some(Prod([alftyp, alftyp]))}, - ]; - }, - ), - ( - "ALFExpr", - { - [ - {name: "NumLit", arg: Some(Int)}, - {name: "Plus", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Times", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Minus", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Eq", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Lt", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Gt", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Neg", arg: Some(alfexpr)}, - {name: "BoolLit", arg: Some(Bool)}, - {name: "If", arg: Some(Prod([alfexpr, alfexpr, alfexpr]))}, - {name: "Var", arg: Some(String)}, - {name: "Let", arg: Some(Prod([String, alfexpr, alfexpr]))}, - {name: "Fun", arg: Some(Prod([String, alftyp, alfexpr]))}, - {name: "Ap", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "Pair", arg: Some(Prod([alfexpr, alfexpr]))}, - {name: "PrjL", arg: Some(alfexpr)}, - {name: "PrjR", arg: Some(alfexpr)}, - { - name: "LetPair", - arg: Some(Prod([String, String, alfexpr, alfexpr])), - }, - ]; - }, - ), -]; - -let is_typ_var = name => List.assoc_opt(name, adts); - -let tags: list((string, Typ.t)) = - List.map( - ((name, tags)) => { - List.map( - adt => - ( - adt.name, - switch (adt.arg) { - | None => Typ.Var(name) - | Some(typ) => Arrow(typ, Var(name)) - }, - ), - tags, - ) - }, - adts, - ) - |> List.flatten; - -let get_tag_typ = (tag_name: string): option(Typ.t) => - List.assoc_opt(tag_name, tags); - -// Check type names are unique -assert(Util.ListUtil.are_duplicates(List.map(fst, adts))); -// Check tag names are unique -assert(Util.ListUtil.are_duplicates(List.map(fst, tags))); diff --git a/src/haz3lcore/statics/CoCtx.re b/src/haz3lcore/statics/CoCtx.re new file mode 100644 index 0000000000..7cbcc51b97 --- /dev/null +++ b/src/haz3lcore/statics/CoCtx.re @@ -0,0 +1,61 @@ +open Sexplib.Std; + +/* Co-contexts: + + A typing co-context (dual to a typing context), is a map between + variable names and a list of that variable's uses within some scope. + For each use, we retain the unique id and expected type of the use site. + The co-ctx, along with the ctx, can be used to determine free and unused variables. + + The following definitions are useful: + + 1. A locally free variable (in an expression) is one + that occurs in the co_ctx of that expression. + 2. A global free variable (in the program) is one that + occurs in the co_ctx but not the ctx of some expression + 3. A locally unused variable (in an expression) is one that + occurs in the ctx but not the co-ctx of that expression + 4. A global unused variable (in the program) is one that + occurs in the ctx but not the co_ctx of some expression + + The following theorems should hold: + + A. To determine if a variable is globally free, it suffices to consider + expressions which are variable references (locus of ctx lookups) + B. To determine if a variable is globally unused, it suffices to consider + expressions which are the bodies of binding forms (locus of ctx extensions) + + */ + +[@deriving (show({with_path: false}), sexp, yojson)] +type entry = { + id: Id.t, + expected_ty: Typ.t, +}; + +/* Each co-context entry is a list of the uses of a variable + within some scope, including their type demands */ +[@deriving (show({with_path: false}), sexp, yojson)] +type t = VarMap.t_(list(entry)); + +let empty: t = VarMap.empty; + +let mk = (ctx_before: Ctx.t, ctx_after, co_ctx: t): t => { + let added_bindings = Ctx.added_bindings(ctx_after, ctx_before); + VarMap.filter( + ((name, _)) => + switch (Ctx.lookup_var(added_bindings, name)) { + | None => true + | Some(_) => false + }, + co_ctx, + ); +}; + +/* Note: this currently shadows in the case of duplicates */ +let union: list(t) => t = + List.fold_left((co_ctx1, co_ctx2) => co_ctx1 @ co_ctx2, []); + +let singleton = (name, id, expected_ty): t => [ + (name, [{id, expected_ty}]), +]; diff --git a/src/haz3lcore/statics/Constructor.re b/src/haz3lcore/statics/Constructor.re new file mode 100644 index 0000000000..6515fd2f97 --- /dev/null +++ b/src/haz3lcore/statics/Constructor.re @@ -0,0 +1,6 @@ +open Sexplib.Std; + +[@deriving (show({with_path: false}), sexp, yojson)] +type t = string; + +let equal = String.equal; diff --git a/src/haz3lcore/statics/ConstructorMap.re b/src/haz3lcore/statics/ConstructorMap.re new file mode 100644 index 0000000000..c9ff0667dc --- /dev/null +++ b/src/haz3lcore/statics/ConstructorMap.re @@ -0,0 +1,101 @@ +open Util.OptUtil.Syntax; +open Sexplib.Std; + +[@deriving (show({with_path: false}), sexp, yojson)] +type binding('a) = (Constructor.t, 'a); + +[@deriving (show({with_path: false}), sexp, yojson)] +type t('a) = list(binding('a)); + +let compare = compare; + +let empty: t('a) = []; + +let is_empty: t('a) => bool = + fun + | [] => true + | _ => false; + +let rec add = (ctr: Constructor.t, value: 'a, map: t('a)): t('a) => + switch (map) { + | [] => [(ctr, value)] + | [(ctr', value') as head, ...tail] => + if (Constructor.equal(ctr, ctr')) { + if (value === value') { + map; + } else { + [(ctr, value), ...tail]; + }; + } else { + [head, ...add(ctr, value, tail)]; + } + }; + +let singleton = (ctr: Constructor.t, value: 'a): t('a) => [(ctr, value)]; + +let compare_bindings = + ((ctr1, _): binding('a), (ctr2, _): binding('a)): int => + compare(ctr1, ctr2); + +/* compares ctrs only */ +let equal = (val_equal: ('a, 'a) => bool, map1: t('a), map2: t('a)): bool => { + let equal_bindings = + ( + val_equal: ('a, 'a) => bool, + (ctr1, val1): binding('a), + (ctr2, val2): binding('a), + ) + : bool => + Constructor.equal(ctr1, ctr2) && val_equal(val1, val2); + map1 === map2 + || { + let map1 = List.fast_sort(compare_bindings, map1); + let map2 = List.fast_sort(compare_bindings, map2); + List.equal(equal_bindings(val_equal), map1, map2); + }; +}; + +let cardinal: t('a) => int = List.length; + +let ctrs_of = (m: list((Constructor.t, 'a))): list(Constructor.t) => + List.map(fst, m); + +let same_constructors_same_order = (map1: t('a), map2: t('a)): bool => + cardinal(map1) === cardinal(map2) + && List.for_all2(Constructor.equal, ctrs_of(map1), ctrs_of(map2)); + +let ctrs_equal = (map1: t('a), map2: t('a)): bool => { + let ctrs1 = ctrs_of(map1); + let ctrs2 = ctrs_of(map2); + ctrs1 === ctrs2 + || List.fast_sort(compare, ctrs1) == List.fast_sort(compare, ctrs2); +}; + +let for_all: (binding('a) => bool, t('a)) => bool = List.for_all; + +let bindings: t('a) => list(binding('a)) = x => x; + +let find_opt = (ctr: Constructor.t, map: t('a)): option('a) => { + let+ binding = List.find_opt(((k, _)) => Constructor.equal(ctr, k), map); + snd(binding); +}; + +let map = (f: 'a => 'b, m: t('a)): t('b) => { + let (ctrs, vals) = List.split(m); + let vals = List.map(f, vals); + List.combine(ctrs, vals); +}; + +/* sorts on ctrs only */ +let sort = (map: t('a)): t('a) => { + List.fast_sort(compare_bindings, map); +}; + +let of_list: list(binding('a)) => t('a) = x => x; + +let rec is_ground = (is_ground_value: 'a => bool, map: t('a)): bool => + switch (map) { + | [] => true + | [(_, head), ...tail] => + is_ground_value(head) && tail |> is_ground(is_ground_value) + }; diff --git a/src/haz3lcore/statics/Ctx.re b/src/haz3lcore/statics/Ctx.re index 2fd801e3bc..1b1ccffd2c 100644 --- a/src/haz3lcore/statics/Ctx.re +++ b/src/haz3lcore/statics/Ctx.re @@ -1,108 +1 @@ -open Sexplib.Std; - -[@deriving (show({with_path: false}), sexp, yojson)] -type var_entry = { - name: Token.t, - id: Id.t, - typ: Typ.t, -}; - -[@deriving (show({with_path: false}), sexp, yojson)] -type entry = - | VarEntry(var_entry) - | TVarEntry({ - name: Token.t, - id: Id.t, - kind: Kind.t, - }); - -let get_id = (entry: entry) => - switch (entry) { - | VarEntry({id, _}) => id - | TVarEntry({id, _}) => id - }; - -[@deriving (show({with_path: false}), sexp, yojson)] -type t = list(entry); - -[@deriving (show({with_path: false}), sexp, yojson)] -type co_item = { - id: Id.t, - mode: Typ.mode, -}; - -[@deriving (show({with_path: false}), sexp, yojson)] -type co_entry = list(co_item); - -[@deriving (show({with_path: false}), sexp, yojson)] -type co = VarMap.t_(co_entry); - -let empty = VarMap.empty; - -let extend = (entry: entry, ctx: t) => [entry, ...ctx]; - -let lookup_var = (ctx: t, name: string): option(var_entry) => - List.find_map( - entry => - switch (entry) { - | VarEntry(var) => - if (var.name == name) { - Some(var); - } else { - None; - } - | TVarEntry(_) => None - }, - ctx, - ); - -let subtract_typ = (ctx: t, free: co): co => - VarMap.filter( - ((k, _)) => - switch (lookup_var(ctx, k)) { - | None => true - | Some(_) => false - }, - free, - ); - -let subtract_prefix = (ctx: t, prefix_ctx: t): option(t) => { - // NOTE: does not check that the prefix is an actual prefix - let prefix_length = List.length(prefix_ctx); - let ctx_length = List.length(ctx); - if (prefix_length > ctx_length) { - None; - } else { - Some( - List.rev( - Util.ListUtil.sublist((prefix_length, ctx_length), List.rev(ctx)), - ), - ); - }; -}; - -//TODO(andrew): is this correct in the case of duplicates? -let union: list(co) => co = - List.fold_left((free1, free2) => free1 @ free2, []); - -module VarSet = Set.Make(Token); - -// Note: filter out duplicates when rendering -let filter_duplicates = (ctx: t): t => - ctx - |> List.fold_left( - ((ctx, term_set, typ_set), entry) => { - switch (entry) { - | VarEntry({name, _}) => - VarSet.mem(name, term_set) - ? (ctx, term_set, typ_set) - : ([entry, ...ctx], VarSet.add(name, term_set), typ_set) - | TVarEntry({name, _}) => - VarSet.mem(name, term_set) - ? (ctx, term_set, typ_set) - : ([entry, ...ctx], term_set, VarSet.add(name, typ_set)) - } - }, - ([], VarSet.empty, VarSet.empty), - ) - |> (((ctx, _, _)) => List.rev(ctx)); +include TypBase.Ctx; diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re new file mode 100644 index 0000000000..c7c5985c0a --- /dev/null +++ b/src/haz3lcore/statics/Info.re @@ -0,0 +1,480 @@ +open Sexplib.Std; +open Util; +open OptUtil.Syntax; +open Term; + +/* INFO.re + + This module defines the cursor INFO data structure, which is used + to represent the static information associated with a term in the + AST. This includes the term itself, and information related to + typing and syntax, included erroneous states. + + Each term is assigned a STATUS, which is directly used to determine + the message displayed to the user in CursorInspector.re. Each sort + has its own status datatype, which is divided into OK states (not + in error holes) and ERROR states (in error holes). + + Regardless of errors, every expression & pattern term is ultimately + assigned a FIXED TYPE, which is the type of the term after hole + fixing; that is, all otherwise ill-typed terms are considered to + be 'wrapped in non-empty holes', i.e. assigned an Unknown type. + + Fixed types are determined by reconcilling two sources of type + information: the SELF (Self.re), representing the type information + derivable from a term in isolation, and the MODE (Mode.re), + representing the expected type information imposed by the surrounding + syntactic context. A successful reconcilliation results in an OK + status; otherwise, an ERROR status, but in both cases, a fixed type + is determined. + + */ + +/* The ids of a term's ancestors in the AST */ +[@deriving (show({with_path: false}), sexp, yojson)] +type ancestors = list(Id.t); + +[@deriving (show({with_path: false}), sexp, yojson)] +type error_inconsistent = + /* Self type (syn) inconsistent with expected type (ana) */ + | Expectation({ + ana: Typ.t, + syn: Typ.t, + }) + /* Inconsistent match or listlit */ + | Internal(list(Typ.t)) + /* Bad function position */ + | WithArrow(Typ.t); + +[@deriving (show({with_path: false}), sexp, yojson)] +type error_no_type = + /* Invalid expression token, treated as hole */ + | BadToken(Token.t) + /* Sum constructor neiter bound nor in ana type */ + | FreeConstructor(Constructor.t); + +/* Errors which can apply to either expression or patterns */ +[@deriving (show({with_path: false}), sexp, yojson)] +type error_common = + /* No type can be assigned */ + | NoType(error_no_type) + /* Assigned type inconsistent with expectation */ + | Inconsistent(error_inconsistent); + +[@deriving (show({with_path: false}), sexp, yojson)] +type error_exp = + | FreeVariable(Var.t) /* Unbound variable (not in typing context) */ + | Common(error_common); + +[@deriving (show({with_path: false}), sexp, yojson)] +type error_pat = + | ExpectedConstructor /* Only construtors can be applied */ + | Common(error_common); + +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_ana = + /* The expected (ana) type and the self (syn) type are + consistent, as witnessed by their joint type (join) */ + | Consistent({ + ana: Typ.t, + syn: Typ.t, + join: Typ.t, + }) + /* A match expression or list literal which, in synthetic position, + would be marked as internally inconsistent, but is considered + fine as the expected type provides a consistent lower bound + (often Unknown) for the types of the branches/elements */ + | InternallyInconsistent({ + ana: Typ.t, + nojoin: list(Typ.t), + }); + +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_common = + | Syn(Typ.t) + | Ana(ok_ana); + +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_exp = ok_common; + +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_pat = ok_common; + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_common = + | InHole(error_common) + | NotInHole(ok_common); + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_exp = + | InHole(error_exp) + | NotInHole(ok_exp); + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_pat = + | InHole(error_pat) + | NotInHole(ok_pat); + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_variant = + | Unique + | Duplicate; + +/* Expectation imposed on a type by the parent form. + TODO: This is fundamentally syntactic and should + eventually be reimplemeted via a seperate sort */ +[@deriving (show({with_path: false}), sexp, yojson)] +type typ_expects = + | TypeExpected + | ConstructorExpected(status_variant, Typ.t) + | VariantExpected(status_variant, Typ.t); + +/* Type term errors + TODO: The three additional errors statuses + are fundamentally syntactic and should when + possible be reimplemeted via a seperate sort */ +[@deriving (show({with_path: false}), sexp, yojson)] +type error_typ = + | BadToken(Token.t) /* Invalid token, treated as type hole */ + | FreeTypeVariable(TypVar.t) /* Free type variable */ + | DuplicateConstructor(Constructor.t) /* Duplicate ctr in same sum */ + | WantTypeFoundAp + | WantConstructorFoundType(Typ.t) + | WantConstructorFoundAp; + +/* Type ok statuses for cursor inspector */ +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_typ = + | Variant(Constructor.t, Typ.t) + | VariantIncomplete(Typ.t) + | TypeAlias(TypVar.t, Typ.t) + | Type(Typ.t); + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_typ = + | InHole(error_typ) + | NotInHole(ok_typ); + +[@deriving (show({with_path: false}), sexp, yojson)] +type type_var_err = + | Other + | NotCapitalized; + +/* Type pattern term errors */ +[@deriving (show({with_path: false}), sexp, yojson)] +type error_tpat = + | ShadowsType(TypVar.t) + | NotAVar(type_var_err); + +/* Type pattern ok statuses for cursor inspector */ +[@deriving (show({with_path: false}), sexp, yojson)] +type ok_tpat = + | Empty + | Var(TypVar.t); + +[@deriving (show({with_path: false}), sexp, yojson)] +type status_tpat = + | NotInHole(ok_tpat) + | InHole(error_tpat); + +[@deriving (show({with_path: false}), sexp, yojson)] +type exp = { + term: UExp.t, /* The term under consideration */ + ancestors, /* Ascending list of containing term ids */ + ctx: Ctx.t, /* Typing context for the term */ + mode: Mode.t, /* Parental type expectations; see Mode.re */ + self: Self.exp, /* Expectation-independent type info; see Self.re */ + co_ctx: CoCtx.t, /* Locally unbound variables; see CoCtx.re */ + cls: Term.Cls.t, /* derived */ + status: status_exp, /* derived: cursor inspector display */ + ty: Typ.t /* derived: type after hole fixing */ +}; + +[@deriving (show({with_path: false}), sexp, yojson)] +type pat = { + term: UPat.t, + ancestors, + ctx: Ctx.t, + mode: Mode.t, + self: Self.pat, + cls: Term.Cls.t, /* derived */ + status: status_pat, /* derived: cursor inspector display */ + ty: Typ.t /* derived: type after hole fixing */ +}; + +[@deriving (show({with_path: false}), sexp, yojson)] +type typ = { + term: UTyp.t, + ancestors, + ctx: Ctx.t, + expects: typ_expects, + cls: Term.Cls.t, /* derived */ + status: status_typ, /* derived: cursor inspector display */ + ty: Typ.t /* derived: represented type */ +}; + +[@deriving (show({with_path: false}), sexp, yojson)] +type tpat = { + term: UTPat.t, + ancestors, + ctx: Ctx.t, + cls: Term.Cls.t, /* derived */ + status: status_tpat /* derived : cursor inspector display */ +}; + +/* The static information collated for each term */ +[@deriving (show({with_path: false}), sexp, yojson)] +type t = + | InfoExp(exp) + | InfoPat(pat) + | InfoTyp(typ) + | InfoTPat(tpat); + +let sort_of: t => Sort.t = + fun + | InfoExp(_) => Exp + | InfoPat(_) => Pat + | InfoTyp(_) => Typ + | InfoTPat(_) => TPat; + +let cls_of: t => Cls.t = + fun + | InfoExp({cls, _}) + | InfoPat({cls, _}) + | InfoTyp({cls, _}) + | InfoTPat({cls, _}) => cls; + +let ctx_of: t => Ctx.t = + fun + | InfoExp({ctx, _}) + | InfoPat({ctx, _}) + | InfoTyp({ctx, _}) + | InfoTPat({ctx, _}) => ctx; + +let exp_co_ctx: exp => CoCtx.t = ({co_ctx, _}) => co_ctx; +let exp_ty: exp => Typ.t = ({ty, _}) => ty; +let pat_ctx: pat => Ctx.t = ({ctx, _}) => ctx; +let pat_ty: pat => Typ.t = ({ty, _}) => ty; + +let rec status_common = + (ctx: Ctx.t, mode: Mode.t, self: Self.t): status_common => + switch (self, mode) { + | (Just(syn), Syn) => NotInHole(Syn(syn)) + | (Just(syn), Ana(ana)) => + switch (Typ.join_fix(ctx, ana, syn)) { + | None => InHole(Inconsistent(Expectation({syn, ana}))) + | Some(join) => NotInHole(Ana(Consistent({ana, syn, join}))) + } + | (Just(syn), SynFun) => + switch ( + Typ.join_fix(ctx, Arrow(Unknown(Internal), Unknown(Internal)), syn) + ) { + | None => InHole(Inconsistent(WithArrow(syn))) + | Some(_) => NotInHole(Syn(syn)) + } + | (IsConstructor({name, syn_ty}), _) => + /* If a ctr is being analyzed against (an arrow type returning) + a sum type having that ctr as a variant, its self type is + considered to be determined by the sum type; otherwise, + check the context for the ctr's type */ + switch (Mode.ctr_ana_typ(ctx, mode, name), syn_ty) { + | (Some(ana_ty), _) => status_common(ctx, mode, Just(ana_ty)) + | (_, Some(syn_ty)) => status_common(ctx, mode, Just(syn_ty)) + | _ => InHole(NoType(FreeConstructor(name))) + } + | (BadToken(name), _) => InHole(NoType(BadToken(name))) + | (IsMulti, _) => NotInHole(Syn(Unknown(Internal))) + | (NoJoin(tys), Ana(ana)) => + NotInHole( + Ana(InternallyInconsistent({ana, nojoin: Typ.of_source(tys)})), + ) + | (NoJoin(tys), Syn | SynFun) => + InHole(Inconsistent(Internal(Typ.of_source(tys)))) + }; + +let status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => + switch (mode, self) { + | (Syn | Ana(_), Common(self_pat)) + | (SynFun, Common(IsConstructor(_) as self_pat)) => + /* Little bit of a hack. Anything other than a bound ctr will, in + function position, have SynFun mode (see Typ.ap_mode). Since we + are prohibiting non-ctrs in ctr applications in patterns for now, + we catch them here, diverting to an ExpectedConstructor error. But we + avoid capturing the second case above, as these will ultimately + get a (more precise) unbound ctr via status_common */ + switch (status_common(ctx, mode, self_pat)) { + | NotInHole(ok_exp) => NotInHole(ok_exp) + | InHole(err_pat) => InHole(Common(err_pat)) + } + | (SynFun, _) => InHole(ExpectedConstructor) + }; + +/* Determines whether an expression or pattern is in an error hole, + depending on the mode, which represents the expectations of the + surrounding syntactic context, and the self which represents the + makeup of the expression / pattern itself. */ +let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => + switch (self, mode) { + | (Free(name), _) => InHole(FreeVariable(name)) + | (Common(self_pat), _) => + switch (status_common(ctx, mode, self_pat)) { + | NotInHole(ok_exp) => NotInHole(ok_exp) + | InHole(err_pat) => InHole(Common(err_pat)) + } + }; + +/* This logic determines whether a type should be put + in a hole or not. It's mostly syntactic, determining + the proper placement of sum type variants and ctrs; + this should be reimplemented in the future as a + separate sort. It also determines semantic properties + such as whether or not a type variable reference is + free, and whether a ctr name is a dupe. */ +let status_typ = + (ctx: Ctx.t, expects: typ_expects, term: TermBase.UTyp.t, ty: Typ.t) + : status_typ => + switch (term.term) { + | Invalid(token) => InHole(BadToken(token)) + | EmptyHole => NotInHole(Type(ty)) + | Var(name) + | Constructor(name) => + switch (expects) { + | VariantExpected(Unique, sum_ty) + | ConstructorExpected(Unique, sum_ty) => + NotInHole(Variant(name, sum_ty)) + | VariantExpected(Duplicate, _) + | ConstructorExpected(Duplicate, _) => + InHole(DuplicateConstructor(name)) + | TypeExpected => + switch (Ctx.is_alias(ctx, name)) { + | false => InHole(FreeTypeVariable(name)) + | true => NotInHole(TypeAlias(name, Typ.weak_head_normalize(ctx, ty))) + } + } + | Ap(t1, t2) => + switch (expects) { + | VariantExpected(status_variant, ty_variant) => + let ty_in = UTyp.to_typ(ctx, t2); + switch (status_variant, t1.term) { + | (Unique, Var(name) | Constructor(name)) => + NotInHole(Variant(name, Arrow(ty_in, ty_variant))) + | _ => NotInHole(VariantIncomplete(Arrow(ty_in, ty_variant))) + }; + | ConstructorExpected(_) => InHole(WantConstructorFoundAp) + | TypeExpected => InHole(WantTypeFoundAp) + } + | _ => + switch (expects) { + | TypeExpected => NotInHole(Type(ty)) + | ConstructorExpected(_) + | VariantExpected(_) => InHole(WantConstructorFoundType(ty)) + } + }; + +let status_tpat = (ctx: Ctx.t, utpat: UTPat.t): status_tpat => + switch (utpat.term) { + | EmptyHole => NotInHole(Empty) + | Var(name) + when Form.is_base_typ(name) || Ctx.lookup_alias(ctx, name) != None => + InHole(ShadowsType(name)) + | Var(name) => NotInHole(Var(name)) + | Invalid(_) => InHole(NotAVar(NotCapitalized)) + | MultiHole(_) => InHole(NotAVar(Other)) + }; + +/* Determines whether any term is in an error hole. */ +let is_error = (ci: t): bool => { + switch (ci) { + | InfoExp({mode, self, ctx, _}) => + switch (status_exp(ctx, mode, self)) { + | InHole(_) => true + | NotInHole(_) => false + } + | InfoPat({mode, self, ctx, _}) => + switch (status_pat(ctx, mode, self)) { + | InHole(_) => true + | NotInHole(_) => false + } + | InfoTyp({expects, ctx, term, ty, _}) => + switch (status_typ(ctx, expects, term, ty)) { + | InHole(_) => true + | NotInHole(_) => false + } + | InfoTPat({term, ctx, _}) => + switch (status_tpat(ctx, term)) { + | InHole(_) => true + | NotInHole(_) => false + } + }; +}; + +/* Determined the type of an expression or pattern 'after hole fixing'; + that is, all ill-typed terms are considered to be 'wrapped in + non-empty holes', i.e. assigned Unknown type. */ +let fixed_typ_ok: ok_pat => Typ.t = + fun + | Syn(syn) => syn + | Ana(Consistent({join, _})) => join + | Ana(InternallyInconsistent({ana, _})) => ana; + +let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => + switch (status_pat(ctx, mode, self)) { + | InHole(_) => Unknown(Internal) + | NotInHole(ok) => fixed_typ_ok(ok) + }; + +let fixed_typ_exp = (ctx, mode: Mode.t, self: Self.exp): Typ.t => + switch (status_exp(ctx, mode, self)) { + | InHole(_) => Unknown(Internal) + | NotInHole(ok) => fixed_typ_ok(ok) + }; + +/* Add derivable attributes for expression terms */ +let derived_exp = + (~uexp: UExp.t, ~ctx, ~mode, ~ancestors, ~self, ~co_ctx): exp => { + let cls = Cls.Exp(UExp.cls_of_term(uexp.term)); + let status = status_exp(ctx, mode, self); + let ty = fixed_typ_exp(ctx, mode, self); + {cls, self, ty, mode, status, ctx, co_ctx, ancestors, term: uexp}; +}; + +/* Add derivable attributes for pattern terms */ +let derived_pat = (~upat: UPat.t, ~ctx, ~mode, ~ancestors, ~self): pat => { + let cls = Cls.Pat(UPat.cls_of_term(upat.term)); + let status = status_pat(ctx, mode, self); + let ty = fixed_typ_pat(ctx, mode, self); + {cls, self, mode, ty, status, ctx, ancestors, term: upat}; +}; + +/* Add derivable attributes for types */ +let derived_typ = (~utyp: UTyp.t, ~ctx, ~ancestors, ~expects): typ => { + let cls: Cls.t = + /* Hack to improve CI display */ + switch (expects, UTyp.cls_of_term(utyp.term)) { + | (VariantExpected(_), Var) => Cls.Typ(Constructor) + | (_, cls) => Cls.Typ(cls) + }; + let ty = UTyp.to_typ(ctx, utyp); + let status = status_typ(ctx, expects, utyp, ty); + {cls, ctx, ancestors, status, expects, ty, term: utyp}; +}; + +/* Add derivable attributes for type patterns */ +let derived_tpat = (~utpat: UTPat.t, ~ctx, ~ancestors): tpat => { + let cls = Cls.TPat(UTPat.cls_of_term(utpat.term)); + let status = status_tpat(ctx, utpat); + {cls, ancestors, status, ctx, term: utpat}; +}; + +/* If the info represents some kind of name binding which + exists in the context, return the id where the binding occurs */ +let get_binding_site = (info: t): option(Id.t) => { + switch (info) { + | InfoExp({term: {term: Var(name) | Constructor(name), _}, ctx, _}) + | InfoPat({term: {term: Constructor(name), _}, ctx, _}) + | InfoTyp({term: {term: Var(name), _}, ctx, _}) => + let+ entry = Ctx.lookup(ctx, name); + Ctx.get_id(entry); + | _ => None + }; +}; diff --git a/src/haz3lcore/statics/Kind.re b/src/haz3lcore/statics/Kind.re index 85cfe1651d..8db5638e94 100644 --- a/src/haz3lcore/statics/Kind.re +++ b/src/haz3lcore/statics/Kind.re @@ -1,3 +1 @@ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Type; +include TypBase.Kind; diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 42fe033450..531b538498 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -73,43 +73,20 @@ let _complete_root = } | root => root; -let is_tuple_exp = ((commas, kids): tiles): option(list(UExp.t)) => - if (commas |> List.map(snd) |> List.for_all((==)(([","], [])))) { - kids - |> List.map( - fun - | Exp(e) => Some(e) - | _ => None, - ) - |> OptUtil.sequence; - } else { - None; - }; -let is_tuple_pat = ((commas, kids): tiles): option(list(UPat.t)) => - if (commas |> List.map(snd) |> List.for_all((==)(([","], [])))) { - kids - |> List.map( - fun - | Pat(p) => Some(p) - | _ => None, - ) - |> OptUtil.sequence; - } else { - None; - }; -let is_tuple_typ = ((commas, kids): tiles): option(list(UTyp.t)) => - if (commas |> List.map(snd) |> List.for_all((==)(([","], [])))) { - kids - |> List.map( - fun - | Typ(ty) => Some(ty) - | _ => None, - ) - |> OptUtil.sequence; +let is_nary = + (is_sort: any => option('sort), delim: Token.t, (delims, kids): tiles) + : option(list('sort)) => + if (delims |> List.map(snd) |> List.for_all((==)(([delim], [])))) { + kids |> List.map(is_sort) |> OptUtil.sequence; } else { None; }; +let is_tuple_exp = is_nary(TermBase.Any.is_exp, ","); +let is_tuple_pat = is_nary(TermBase.Any.is_pat, ","); +let is_tuple_typ = is_nary(TermBase.Any.is_typ, ","); +let is_typ_bsum = is_nary(TermBase.Any.is_typ, "+"); + let is_grout = tiles => Aba.get_as(tiles) |> List.map(snd) |> List.for_all((==)(([" "], []))); @@ -134,12 +111,6 @@ let is_rules = ((ts, kids): tiles): option(Aba.t(UPat.t, UExp.t)) => { Aba.mk(ps, clauses); }; -// let have_sort = (tms: list(any)) => -// tms -// |> List.map( - -// ) - let ids_of_tiles = (tiles: tiles) => List.map(fst, Aba.get_as(tiles)); let ids = fun @@ -175,9 +146,17 @@ let return_dark_hole = (~ids=[], s) => { hole; }; +let parse_sum_term: UTyp.t => UTyp.variant = + fun + | {term: Var(ctr), ids} => Variant(ctr, ids, None) + | {term: Ap({term: Var(ctr), ids: ids_ctr}, u), ids: ids_ap} => + Variant(ctr, ids_ctr @ ids_ap, Some(u)) + | t => BadEntry(t); + let rec go_s = (s: Sort.t, skel: Skel.t, seg: Segment.t): any => switch (s) { | Pat => Pat(pat(unsorted(skel, seg))) + | TPat => TPat(tpat(unsorted(skel, seg))) | Typ => Typ(typ(unsorted(skel, seg))) | Exp => Exp(exp(unsorted(skel, seg))) | Rul => Rul(rul(unsorted(skel, seg))) @@ -207,7 +186,6 @@ and exp = unsorted => { } and exp_term: unsorted => (UExp.term, list(Id.t)) = { let ret = (tm: UExp.term) => (tm, []); - let _unrecog = UExp.Invalid(UnrecognizedTerm); let hole = unsorted => Term.UExp.hole(kids_of_unsorted(unsorted)); fun | Op(tiles) as tm => @@ -219,10 +197,13 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { | ([t], []) when Form.is_empty_list(t) => ret(ListLit([])) | ([t], []) when Form.is_bool(t) => ret(Bool(bool_of_string(t))) | ([t], []) when Form.is_int(t) => ret(Int(int_of_string(t))) - | ([t], []) when Form.is_string(t) => ret(String(t)) + | ([t], []) when Form.is_string(t) => + let s = Re.Str.string_after(t, 1); + let s = Re.Str.string_before(s, String.length(s) - 1); + ret(String(s)); | ([t], []) when Form.is_float(t) => ret(Float(float_of_string(t))) | ([t], []) when Form.is_var(t) => ret(Var(t)) - | ([t], []) when Form.is_tag(t) => ret(Tag(t)) + | ([t], []) when Form.is_ctr(t) => ret(Constructor(t)) | (["(", ")"], [Exp(body)]) => ret(Parens(body)) | (["[", "]"], [Exp(body)]) => switch (body) { @@ -234,6 +215,7 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { Match(scrut, rules), ids, ) + | ([t], []) when t != " " => ret(Invalid(t)) | _ => ret(hole(tm)) } | _ => ret(hole(tm)) @@ -246,6 +228,8 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { | (["-"], []) => UnOp(Int(Minus), r) | (["fun", "->"], [Pat(pat)]) => Fun(pat, r) | (["let", "=", "in"], [Pat(pat), Exp(def)]) => Let(pat, def, r) + | (["type", "=", "in"], [TPat(tpat), Typ(def)]) => + TyAlias(tpat, def, r) | (["if", "then", "else"], [Exp(cond), Exp(conseq)]) => If(cond, conseq, r) | _ => hole(tm) @@ -313,7 +297,6 @@ and pat = unsorted => { } and pat_term: unsorted => (UPat.term, list(Id.t)) = { let ret = (term: UPat.term) => (term, []); - let _unrecog = UPat.Invalid(UnrecognizedTerm); let hole = unsorted => Term.UPat.hole(kids_of_unsorted(unsorted)); fun | Op(tiles) as tm => @@ -326,10 +309,14 @@ and pat_term: unsorted => (UPat.term, list(Id.t)) = { | ([t], []) when Form.is_bool(t) => Bool(bool_of_string(t)) | ([t], []) when Form.is_float(t) => Float(float_of_string(t)) | ([t], []) when Form.is_int(t) => Int(int_of_string(t)) - | ([t], []) when Form.is_string(t) => String(t) + | ([t], []) when Form.is_string(t) => + let s = Re.Str.string_after(t, 1); + let s = Re.Str.string_before(s, String.length(s) - 1); + String(s); | ([t], []) when Form.is_var(t) => Var(t) | ([t], []) when Form.is_wild(t) => Wild - | ([t], []) when Form.is_tag(t) => Tag(t) + | ([t], []) when Form.is_ctr(t) => Constructor(t) + | ([t], []) when t != " " => Invalid(t) | (["(", ")"], [Pat(body)]) => Parens(body) | (["[", "]"], [Pat(body)]) => switch (body) { @@ -369,43 +356,90 @@ and pat_term: unsorted => (UPat.term, list(Id.t)) = { } | tm => ret(hole(tm)); } - and typ = unsorted => { - let term = typ_term(unsorted); - let ids = ids(unsorted); + let (term, inner_ids) = typ_term(unsorted); + let ids = ids(unsorted) @ inner_ids; return(ty => Typ(ty), ids, {ids, term}); } -and typ_term: unsorted => UTyp.term = { - let _unrecog = UTyp.Invalid(UnrecognizedTerm); +and typ_term: unsorted => (UTyp.term, list(Id.t)) = { + let ret = (term: UTyp.term) => (term, []); let hole = unsorted => Term.UTyp.hole(kids_of_unsorted(unsorted)); fun | Op(tiles) as tm => switch (tiles) { | ([(_id, tile)], []) => - switch (tile) { - | ([t], []) when Form.is_empty_tuple(t) => Tuple([]) - | (["Bool"], []) => Bool - | (["Int"], []) => Int - | (["Float"], []) => Float - | (["String"], []) => String - | ([t], []) when Form.is_typ_var(t) => Var(t) - | (["(", ")"], [Typ(body)]) => Parens(body) - | (["[", "]"], [Typ(body)]) => List(body) - | _ => hole(tm) - } - | _ => hole(tm) + ret( + switch (tile) { + | ([t], []) when Form.is_empty_tuple(t) => Tuple([]) + | (["Bool"], []) => Bool + | (["Int"], []) => Int + | (["Float"], []) => Float + | (["String"], []) => String + | ([t], []) when Form.is_typ_var(t) => Var(t) + | (["(", ")"], [Typ(body)]) => Parens(body) + | (["[", "]"], [Typ(body)]) => List(body) + | ([t], []) when t != " " => Invalid(t) + | _ => hole(tm) + }, + ) + | _ => ret(hole(tm)) + } + | Post(Typ(t), tiles) as tm => + switch (tiles) { + | ([(_, (["(", ")"], [Typ(typ)]))], []) => ret(Ap(t, typ)) + | _ => ret(hole(tm)) + } + | Pre(tiles, Typ({term: Sum(t0), ids})) as tm => + /* Case for leading prefix + preceeding a sum */ + switch (tiles) { + | ([(_, (["+"], []))], []) => (Sum(t0), ids) + | _ => ret(hole(tm)) + } + | Pre(tiles, Typ(t)) as tm => + switch (tiles) { + | ([(_, (["+"], []))], []) => ret(Sum([parse_sum_term(t)])) + | _ => ret(hole(tm)) + } + | Bin(Typ(t1), tiles, Typ(t2)) as tm when is_typ_bsum(tiles) != None => + switch (is_typ_bsum(tiles)) { + | Some(between_kids) => + ret(Sum(List.map(parse_sum_term, [t1] @ between_kids @ [t2]))) + | None => ret(hole(tm)) } - | (Pre(_) | Post(_)) as tm => hole(tm) | Bin(Typ(l), tiles, Typ(r)) as tm => switch (is_tuple_typ(tiles)) { - | Some(between_kids) => Tuple([l] @ between_kids @ [r]) + | Some(between_kids) => ret(Tuple([l] @ between_kids @ [r])) | None => switch (tiles) { - | ([(_id, (["->"], []))], []) => Arrow(l, r) - | _ => hole(tm) + | ([(_id, (["->"], []))], []) => ret(Arrow(l, r)) + | _ => ret(hole(tm)) } } - | tm => hole(tm); + | tm => ret(hole(tm)); +} +and tpat = unsorted => { + let term = tpat_term(unsorted); + let ids = ids(unsorted); + return(ty => TPat(ty), ids, {ids, term}); +} +and tpat_term: unsorted => UTPat.term = { + let ret = (term: UTPat.term) => term; + let hole = unsorted => Term.UTPat.hole(kids_of_unsorted(unsorted)); + fun + | Op(tiles) as tm => + switch (tiles) { + | ([(_id, tile)], []) => + ret( + switch (tile) { + | ([t], []) when Form.is_typ_var(t) => Var(t) + | ([t], []) when t != " " => Invalid(t) + | _ => hole(tm) + }, + ) + | _ => ret(hole(tm)) + } + | (Pre(_) | Post(_)) as tm => ret(hole(tm)) + | tm => ret(hole(tm)); } // and rul = unsorted => { diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re new file mode 100644 index 0000000000..cb3a7ab8c9 --- /dev/null +++ b/src/haz3lcore/statics/Mode.re @@ -0,0 +1,126 @@ +open Util; +open OptUtil.Syntax; + +/* MODE.re + + This module defines the (analytic) type expectation imposed by a term's + syntactic context, in particular its immediate parent. The most common + cases are either Syn (no type expectation), or Ana (some type expectation). + + A term's MODE is used in combination with that term's SELF (Self.re) by + to determine that term's STATUS (Info.re), which dictates whether or not + it is placed in a hole, and hence its FIXED TYPE (Info.re). + + (It is conjectured [citation needed] that the Syn mode is functionally + indistinguishable from Ana(Unknown(SynSwitch)), and that this type is + thus vestigial.) + + */ + +[@deriving (show({with_path: false}), sexp, yojson)] +type t = + | SynFun /* Used only in function position of applications */ + | Syn + | Ana(Typ.t); + +let ana: Typ.t => t = ty => Ana(ty); + +/* The expected type imposed by a mode */ +let ty_of: t => Typ.t = + fun + | Ana(ty) => ty + | Syn => Unknown(SynSwitch) + | SynFun => Arrow(Unknown(SynSwitch), Unknown(SynSwitch)); + +let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => + switch (mode) { + | Syn + | SynFun => (Syn, Syn) + | Ana(ty) => + ty + |> Typ.weak_head_normalize(ctx) + |> Typ.matched_arrow + |> TupleUtil.map2(ana) + }; + +let of_prod = (ctx: Ctx.t, mode: t, length): list(t) => + switch (mode) { + | Syn + | SynFun => List.init(length, _ => Syn) + | Ana(ty) => + ty + |> Typ.weak_head_normalize(ctx) + |> Typ.matched_prod(length) + |> List.map(ana) + }; + +let matched_list_normalize = (ctx: Ctx.t, ty: Typ.t): Typ.t => + ty |> Typ.weak_head_normalize(ctx) |> Typ.matched_list; + +let of_cons_hd = (ctx: Ctx.t, mode: t): t => + switch (mode) { + | Syn + | SynFun => Syn + | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) + }; + +let of_cons_tl = (ctx: Ctx.t, mode: t, hd_ty: Typ.t): t => + switch (mode) { + | Syn + | SynFun => Ana(List(hd_ty)) + | Ana(ty) => Ana(List(matched_list_normalize(ctx, ty))) + }; + +let of_list = (ctx: Ctx.t, mode: t): t => + switch (mode) { + | Syn + | SynFun => Syn + | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) + }; + +let of_list_lit = (ctx: Ctx.t, length, mode: t): list(t) => + List.init(length, _ => of_list(ctx, mode)); + +let ctr_ana_typ = (ctx: Ctx.t, mode: t, ctr: Constructor.t): option(Typ.t) => { + /* If a ctr is being analyzed against (an arrow type returning) + a sum type having that ctr as a variant, we consider the + ctr's type to be determined by the sum type */ + switch (mode) { + | Ana(Arrow(_, ty_ana)) + | Ana(ty_ana) => + let* ctrs = Typ.get_sum_constructors(ctx, ty_ana); + let+ (_, ty_entry) = Typ.sum_entry(ctr, ctrs); + switch (ty_entry) { + | None => ty_ana + | Some(ty_in) => Arrow(ty_in, ty_ana) + }; + | _ => None + }; +}; + +let of_ctr_in_ap = (ctx: Ctx.t, mode: t, ctr: Constructor.t): option(t) => + switch (ctr_ana_typ(ctx, mode, ctr)) { + | Some(Arrow(_) as ty_ana) => Some(Ana(ty_ana)) + | Some(ty_ana) => + /* Consider for example "let _ : +Yo = Yo("lol") in..." + Here, the 'Yo' constructor should be in a hole, as it + is nullary but used as unary; we reflect this by analyzing + against an arrow type. Since we can't guess at what the + parameter type might have be, we use Unknown. */ + Some(Ana(Arrow(Unknown(Internal), ty_ana))) + | None => None + }; + +let of_ap = (ctx, mode, ctr: option(Constructor.t)): t => + /* If a ctr application is being analyzed against a sum type for + which that ctr is a variant, then we consider the ctr to be in + analytic mode against an arrow returning that sum type; otherwise + we use the typical mode for function applications */ + switch (ctr) { + | Some(name) => + switch (of_ctr_in_ap(ctx, mode, name)) { + | Some(mode) => mode + | _ => SynFun + } + | None => SynFun + }; diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re new file mode 100644 index 0000000000..611c4b1455 --- /dev/null +++ b/src/haz3lcore/statics/Self.re @@ -0,0 +1,90 @@ +open Sexplib.Std; + +/* SELF.re + + This module defines the SELF data structure, which represents + the synthetic type information derivable from a term independent + of the type expectation (i.e. MODE) of its syntactic context. This + synethetic information is not entirely independent, in that it still + uses the typing context passed down from the syntactic context. + + A term which from which a type can be derived in isolation, that is, + that has a valid synthetic typing judgement, will generally have a SELF + of Just(some_type). (The one current exception are the constructors of labelled + sum types, which are handled specially as their synthetic type + may be 'overwritten' by the analytic expectation) + + The other cases all represent states for which no single type can be + derived, such as syntactic errors, or branching constructs which may + have inconsistent types. + + */ + +[@deriving (show({with_path: false}), sexp, yojson)] +type t = + | Just(Typ.t) /* Just a regular type */ + | NoJoin(list(Typ.source)) /* Inconsistent types for e.g match, listlits */ + | BadToken(Token.t) /* Invalid expression token, treated as hole */ + | IsMulti /* Multihole, treated as hole */ + | IsConstructor({ + name: Constructor.t, + syn_ty: option(Typ.t), + }); /* Constructors have special ana logic */ + +/* Expressions can also be free variables */ +[@deriving (show({with_path: false}), sexp, yojson)] +type exp = + | Free(Var.t) + | Common(t); + +[@deriving (show({with_path: false}), sexp, yojson)] +type pat = + | Common(t); + +/* What the type would be if the position had been + synthetic, so no hole fixing. Returns none if + there's no applicable synthetic rule. */ +let typ_of: (Ctx.t, t) => option(Typ.t) = + _ctx => + fun + | Just(typ) => Some(typ) + | IsConstructor({syn_ty, _}) => syn_ty + | BadToken(_) + | IsMulti + | NoJoin(_) => None; + +let typ_of_exp: (Ctx.t, exp) => option(Typ.t) = + ctx => + fun + | Free(_) => None + | Common(self) => typ_of(ctx, self); + +/* The self of a var depends on the ctx; if the + lookup fails, it is a free variable */ +let of_exp_var = (ctx: Ctx.t, name: Var.t): exp => + switch (Ctx.lookup_var(ctx, name)) { + | None => Free(name) + | Some(var) => Common(Just(var.typ)) + }; + +/* The self of a ctr depends on the ctx, but a + lookup failure doesn't necessarily means its + free; it may be given a type analytically */ +let of_ctr = (ctx: Ctx.t, name: Constructor.t): t => + IsConstructor({ + name, + syn_ty: + switch (Ctx.lookup_ctr(ctx, name)) { + | None => None + | Some({typ, _}) => Some(typ) + }, + }); + +/* The self assigned to things like cases and list literals + which can have internal type inconsistencies. */ +let join = + (wrap: Typ.t => Typ.t, tys: list(Typ.t), ids: list(Id.t), ctx: Ctx.t): t => + switch (Typ.join_all(ctx, tys)) { + | None => NoJoin(List.map2((id, ty) => Typ.{id, ty}, ids, tys)) + | Some(ty) => Just(wrap(ty)) + }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6814b19550..11705afad4 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -1,325 +1,155 @@ -open Sexplib.Std; -open Util; +open Term; -/* STATICS +/* STATICS.re - This module determines the statics semantics of the language. - It takes a term and returns a map which associates the unique - ids of each term to an 'info' data structure which reflects that - term's statics. The statics collected depend on the term's sort, - but every term has a syntactic class (The cls types from Term), - except Invalid terms which Term could not parse. + This module determines the statics semantics of a program. + It makes use of the following modules: - The map generated by this module is intended to be generated once - from a given term and then reused anywhere there is logic which - depends on static information. - */ + INFO.re: Defines the Info.t type which is used to represent the + static STATUS of a term. This STATUS can be either OK or ERROR, + and is determined by reconcilling two sources of typing information, + the MODE and the SELF. -/* Expressions are assigned a mode (reflecting the static expectations - if any of their syntactic parent), a self (reflecting what their - statics would be in isolation), a context (variables in scope), and - free (variables occuring free in the expression. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type info_exp = { - cls: Term.UExp.cls, - term: Term.UExp.t, - mode: Typ.mode, - self: Typ.self, - ctx: Ctx.t, - free: Ctx.co, - // TODO: add derived attributes like error_status and typ_after_fix? -}; - -/* Patterns are assigned a mode (reflecting the static expectations - if any of their syntactic parent) and a self (reflecting what their - statics would be in isolation), a context (variables in scope) */ -[@deriving (show({with_path: false}), sexp, yojson)] -type info_pat = { - cls: Term.UPat.cls, - term: Term.UPat.t, - mode: Typ.mode, - self: Typ.self, - ctx: Ctx.t // TODO: detect in-pattern shadowing -}; - -/* (Syntactic) Types are assigned their corresponding semantic type. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type info_typ = { - cls: Term.UTyp.cls, - term: Term.UTyp.t, - self: Typ.self, -}; - -[@deriving (show({with_path: false}), sexp, yojson)] -type info_rul = { - cls: Term.URul.cls, - term: Term.UExp.t, -}; - -/* The Info aka Cursorinfo assigned to each subterm. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Invalid(TermBase.parse_flag) - | InfoExp(info_exp) - | InfoPat(info_pat) - | InfoTyp(info_typ) - | InfoRul(info_rul); - -/* The InfoMap collating all info for a composite term */ -type map = Id.Map.t(t); + MODE.re: Defines the Mode.t type which is used to represent the + typing expectations imposed by a term's ancestors. -let terms = (map: map): Id.Map.t(Term.any) => - map - |> Id.Map.filter_map(_ => - fun - | Invalid(_) => None - | InfoExp({term, _}) => Some(Term.Exp(term)) - | InfoPat({term, _}) => Some(Term.Pat(term)) - | InfoTyp({term, _}) => Some(Term.Typ(term)) - | InfoRul({term, _}) => Some(Term.Exp(term)) - ); + SELF.re: Define the Self.t type which is used to represent the + type information derivable from the term itself. -/* Static error classes */ -[@deriving (show({with_path: false}), sexp, yojson)] -type error = - | Free(Typ.free_errors) - | Multi - | NoFun(Typ.t) - | SynInconsistentBranches(list(Typ.t)) - | TypeInconsistent(Typ.t, Typ.t); + The point of STATICS.re itself is to derive a map between each + term's unique id and that term's static INFO. The below functions + are intended mostly as infrastructure: The point is to define a + traversal through the syntax tree which, for each term, passes + down the MODE, passes up the SELF, calculates the INFO, and adds + it to the map. -/* Statics non-error classes */ -[@deriving (show({with_path: false}), sexp, yojson)] -type happy = - | SynConsistent(Typ.t) - | AnaConsistent(Typ.t, Typ.t, Typ.t) //ana, syn, join - | AnaInternalInconsistent(Typ.t, list(Typ.t)) // ana, branches - | AnaExternalInconsistent(Typ.t, Typ.t); // ana, syn + The architectural intention here is that most type-manipulation + logic is defined in INFO, MODE, and SELF, and the STATICS module + itself is dedicated to the piping necessary to (A) introduce and + (B) propagate the necessary information through the syntax tree. -/* The error status which 'wraps' each term. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type error_status = - | InHole(error) - | NotInHole(happy); + */ -/* Determines whether an expression or pattern is in an error hole, - depending on the mode, which represents the expectations of the - surrounding syntactic context, and the self which represents the - makeup of the expression / pattern itself. */ -let error_status = (mode: Typ.mode, self: Typ.self): error_status => - switch (mode, self) { - | (SynFun, Just(ty)) => - switch (Typ.join(Arrow(Unknown(Internal), Unknown(Internal)), ty)) { - | None => InHole(NoFun(ty)) - | Some(_) => NotInHole(SynConsistent(ty)) - } - | (SynFun, Joined(_wrap, tys_syn)) => - let tys_syn = Typ.source_tys(tys_syn); - switch (Typ.join_all(tys_syn)) { - | None => InHole(SynInconsistentBranches(tys_syn)) - | Some(ty_joined) => - switch ( - Typ.join(Arrow(Unknown(Internal), Unknown(Internal)), ty_joined) - ) { - | None => InHole(NoFun(ty_joined)) - | Some(_) => NotInHole(SynConsistent(ty_joined)) - } - }; - | (Syn | SynFun | Ana(_), Free(free_error)) => InHole(Free(free_error)) - | (Syn | SynFun | Ana(_), Multi) => - NotInHole(SynConsistent(Unknown(Internal))) - | (Syn, Just(ty)) => NotInHole(SynConsistent(ty)) - | (Syn, Joined(wrap, tys_syn)) => - let tys_syn = Typ.source_tys(tys_syn); - switch (Typ.join_all(tys_syn)) { - | None => InHole(SynInconsistentBranches(tys_syn)) - | Some(ty_joined) => NotInHole(SynConsistent(wrap(ty_joined))) - }; - | (Ana(ty_ana), Just(ty_syn)) => - switch (Typ.join(ty_ana, ty_syn)) { - | None => InHole(TypeInconsistent(ty_syn, ty_ana)) - | Some(ty_join) => NotInHole(AnaConsistent(ty_ana, ty_syn, ty_join)) - } - | (Ana(ty_ana), Joined(wrap, tys_syn)) => - // TODO: review logic of these cases - switch (Typ.join_all(Typ.source_tys(tys_syn))) { - | Some(ty_syn) => - let ty_syn = wrap(ty_syn); - switch (Typ.join(ty_syn, ty_ana)) { - | None => NotInHole(AnaExternalInconsistent(ty_ana, ty_syn)) - | Some(ty_join) => NotInHole(AnaConsistent(ty_syn, ty_ana, ty_join)) - }; - | None => - NotInHole(AnaInternalInconsistent(ty_ana, Typ.source_tys(tys_syn))) - } - }; +module Info = Info; -/* Determines whether any term is in an error hole. Currently types cannot - be in error, and Invalids (things to which Term was unable to assign a - parse) are always in error. The error status of expressions and patterns - are determined by error_status above. */ -let is_error = (ci: t): bool => { - switch (ci) { - | Invalid(Secondary) => false - | Invalid(_) => true - | InfoExp({mode, self, _}) - | InfoPat({mode, self, _}) => - switch (error_status(mode, self)) { - | InHole(_) => true - | NotInHole(_) => false - } - | InfoTyp({self, _}) => - switch (self) { - | Free(TypeVariable) => true - | _ => false - } - | InfoRul(_) => false //TODO - }; +module Map = { + [@deriving (show({with_path: false}), sexp, yojson)] + type t = Id.Map.t(Info.t); }; -/* Determined the type of an expression or pattern 'after hole wrapping'; - that is, all ill-typed terms are considered to be 'wrapped in - non-empty holes', i.e. assigned Unknown type. */ -let typ_after_fix = (mode: Typ.mode, self: Typ.self): Typ.t => - switch (error_status(mode, self)) { - | InHole(_) => Unknown(Internal) - | NotInHole(SynConsistent(t)) => t - | NotInHole(AnaConsistent(_, _, ty_join)) => ty_join - | NotInHole(AnaExternalInconsistent(ty_ana, _)) => ty_ana - | NotInHole(AnaInternalInconsistent(ty_ana, _)) => ty_ana - }; - -/* The type of an expression after hole wrapping */ -let exp_typ = (m: map, e: Term.UExp.t): Typ.t => - switch (Id.Map.find_opt(Term.UExp.rep_id(e), m)) { - | Some(InfoExp({mode, self, _})) => typ_after_fix(mode, self) - | Some(InfoPat(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) - | None => failwith(__LOC__ ++ ": XXX") - }; - -let exp_self_typ_id = (m: map, id): Typ.t => - switch (Id.Map.find_opt(id, m)) { - | Some(InfoExp({self, _})) => Typ.t_of_self(self) - | Some(InfoPat(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) - | None => failwith(__LOC__ ++ ": XXX") - }; - -let exp_self_typ = (m: map, e: Term.UExp.t): Typ.t => - exp_self_typ_id(m, Term.UExp.rep_id(e)); - -let exp_mode_id = (m: map, id): Typ.mode => - switch (Id.Map.find_opt(id, m)) { - | Some(InfoExp({mode, _})) => mode - | Some(InfoPat(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) - | None => failwith(__LOC__ ++ ": XXX") - }; - -let exp_mode = (m: map, e: Term.UExp.t): Typ.mode => - exp_mode_id(m, Term.UExp.rep_id(e)); - -/* The type of a pattern after hole wrapping */ -let pat_typ = (m: map, p: Term.UPat.t): Typ.t => - switch (Id.Map.find_opt(Term.UPat.rep_id(p), m)) { - | Some(InfoPat({mode, self, _})) => typ_after_fix(mode, self) - | Some(InfoExp(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) - | None => failwith(__LOC__ ++ ": XXX") - }; -let pat_self_typ = (m: map, p: Term.UPat.t): Typ.t => - switch (Id.Map.find_opt(Term.UPat.rep_id(p), m)) { - | Some(InfoPat({self, _})) => Typ.t_of_self(self) - | Some(InfoExp(_) | InfoTyp(_) | InfoRul(_) | Invalid(_)) - | None => failwith(__LOC__ ++ ": XXX") - }; - -let union_m = +let map_m = (f, xs, m: Map.t) => List.fold_left( - (m1, m2) => Id.Map.union((_, _, b) => Some(b), m1, m2), - Id.Map.empty, + ((xs, m), x) => f(x, m) |> (((x, m)) => (xs @ [x], m)), + ([], m), + xs, ); -let add_info = (ids, info: 'a, m: Ptmap.t('a)) => - ids - |> List.map(id => Id.Map.singleton(id, info)) - |> List.fold_left(Id.Map.disj_union, m); +let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => + ids |> List.fold_left((m, id) => Id.Map.add(id, info, m), m); let extend_let_def_ctx = - (ctx: Ctx.t, pat: Term.UPat.t, pat_ctx: Ctx.t, def: Term.UExp.t) => - if (Term.UPat.is_tuple_of_arrows(pat) - && Term.UExp.is_tuple_of_functions(def)) { - VarMap.concat(ctx, pat_ctx); + (ctx: Ctx.t, pat: UPat.t, pat_ctx: Ctx.t, def: UExp.t): Ctx.t => + if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { + pat_ctx; } else { ctx; }; -let typ_exp_binop_bin_int: Term.UExp.op_bin_int => Typ.t = +let typ_exp_binop_bin_int: UExp.op_bin_int => Typ.t = fun | (Plus | Minus | Times | Power | Divide) as _op => Int | (LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual | Equals) as _op => Bool; -let typ_exp_binop_bin_float: Term.UExp.op_bin_float => Typ.t = +let typ_exp_binop_bin_float: UExp.op_bin_float => Typ.t = fun | (Plus | Minus | Times | Power | Divide) as _op => Float | (LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual | Equals) as _op => Bool; -let typ_exp_binop_bin_string: Term.UExp.op_bin_string => Typ.t = +let typ_exp_binop_bin_string: UExp.op_bin_string => Typ.t = fun | Equals as _op => Bool; -let typ_exp_binop: Term.UExp.op_bin => (Typ.t, Typ.t, Typ.t) = +let typ_exp_binop: UExp.op_bin => (Typ.t, Typ.t, Typ.t) = fun | Bool(And | Or) => (Bool, Bool, Bool) | Int(op) => (Int, Int, typ_exp_binop_bin_int(op)) | Float(op) => (Float, Float, typ_exp_binop_bin_float(op)) | String(op) => (String, String, typ_exp_binop_bin_string(op)); -let typ_exp_unop: Term.UExp.op_un => (Typ.t, Typ.t) = +let typ_exp_unop: UExp.op_un => (Typ.t, Typ.t) = fun | Int(Minus) => (Int, Int); -let rec any_to_info_map = (~ctx: Ctx.t, any: Term.any): (Ctx.co, map) => +let rec any_to_info_map = + (~ctx: Ctx.t, ~ancestors, any: any, m: Map.t): (CoCtx.t, Map.t) => switch (any) { | Exp(e) => - let (_, co, map) = uexp_to_info_map(~ctx, e); - (co, map); + let (Info.{co_ctx, _}, m) = uexp_to_info_map(~ctx, ~ancestors, e, m); + (co_ctx, m); | Pat(p) => - let (_, _, map) = upat_to_info_map(~is_synswitch=false, ~ctx, p); - (VarMap.empty, map); - | Typ(ty) => - let (_, map) = utyp_to_info_map(ty); - (VarMap.empty, map); - // TODO(d) consider Rul case + let m = + upat_to_info_map(~is_synswitch=false, ~ancestors, ~ctx, p, m) |> snd; + (VarMap.empty, m); + | TPat(tp) => ( + VarMap.empty, + utpat_to_info_map(~ctx, ~ancestors, tp, m) |> snd, + ) + | Typ(ty) => ( + VarMap.empty, + utyp_to_info_map(~ctx, ~ancestors, ty, m) |> snd, + ) | Rul(_) | Nul () - | Any () => (VarMap.empty, Id.Map.empty) + | Any () => (VarMap.empty, m) } +and multi = (~ctx, ~ancestors, m, tms) => + List.fold_left( + ((co_ctxs, m), any) => { + let (co_ctx, m) = any_to_info_map(~ctx, ~ancestors, any, m); + (co_ctxs @ [co_ctx], m); + }, + ([], m), + tms, + ) and uexp_to_info_map = - (~ctx: Ctx.t, ~mode=Typ.Syn, {ids, term} as uexp: Term.UExp.t) - : (Typ.t, Ctx.co, map) => { + ( + ~ctx: Ctx.t, + ~mode=Mode.Syn, + ~ancestors, + {ids, term} as uexp: UExp.t, + m: Map.t, + ) + : (Info.exp, Map.t) => { /* Maybe switch mode to syn */ let mode = switch (mode) { - | Ana(Unknown(SynSwitch)) => Typ.Syn + | Ana(Unknown(SynSwitch)) => Mode.Syn | _ => mode }; - let cls = Term.UExp.cls_of_term(term); - let go = uexp_to_info_map(~ctx); - let add = (~self, ~free, m) => ( - typ_after_fix(mode, self), - free, - add_info(ids, InfoExp({cls, self, mode, ctx, free, term: uexp}), m), - ); - let atomic = self => add(~self, ~free=[], Id.Map.empty); + let add' = (~self, ~co_ctx, m) => { + let info = + Info.derived_exp(~uexp, ~ctx, ~mode, ~ancestors, ~self, ~co_ctx); + (info, add_info(ids, InfoExp(info), m)); + }; + let add = (~self, ~co_ctx, m) => add'(~self=Common(self), ~co_ctx, m); + let ancestors = [UExp.rep_id(uexp)] @ ancestors; + let go' = uexp_to_info_map(~ancestors); + let go = go'(~ctx); + let map_m_go = m => + List.fold_left2( + ((es, m), mode, e) => + go(~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + ); + let go_pat = upat_to_info_map(~ctx, ~ancestors); + let atomic = self => add(~self, ~co_ctx=CoCtx.empty, m); switch (term) { - | Invalid(msg) => ( - Unknown(Internal), - [], - add_info(ids, Invalid(msg), Id.Map.empty), - ) | MultiHole(tms) => - let (free, maps) = tms |> List.map(any_to_info_map(~ctx)) |> List.split; - add(~self=Multi, ~free=Ctx.union(free), union_m(maps)); + let (co_ctxs, m) = multi(~ctx, ~ancestors, m, tms); + add(~self=IsMulti, ~co_ctx=CoCtx.union(co_ctxs), m); + | Invalid(token) => atomic(BadToken(token)) | EmptyHole => atomic(Just(Unknown(Internal))) | Triv => atomic(Just(Prod([]))) | Bool(_) => atomic(Just(Bool)) @@ -328,192 +158,198 @@ and uexp_to_info_map = | String(_) => atomic(Just(String)) | ListLit([]) => atomic(Just(List(Unknown(Internal)))) | ListLit(es) => - let modes = List.init(List.length(es), _ => Typ.matched_list_mode(mode)); - let e_ids = List.map(Term.UExp.rep_id, es); - let infos = List.map2((e, mode) => go(~mode, e), es, modes); - let tys = List.map(((ty, _, _)) => ty, infos); - let self: Typ.self = - switch (Typ.join_all(tys)) { - | None => - Joined( - ty => List(ty), - List.map2((id, ty) => Typ.{id, ty}, e_ids, tys), - ) - | Some(ty) => Just(List(ty)) - }; - let free = Ctx.union(List.map(((_, f, _)) => f, infos)); - let m = union_m(List.map(((_, _, m)) => m, infos)); - add(~self, ~free, m); - | Cons(e1, e2) => - let mode_e = Typ.matched_list_mode(mode); - let (ty1, free1, m1) = go(~mode=mode_e, e1); - let (_, free2, m2) = go(~mode=Ana(List(ty1)), e2); + let ids = List.map(UExp.rep_id, es); + let modes = Mode.of_list_lit(ctx, List.length(es), mode); + let (es, m) = map_m_go(m, modes, es); + let tys = List.map(Info.exp_ty, es); + add( + ~self=Self.join(ty => List(ty), tys, ids, ctx), + ~co_ctx=CoCtx.union(List.map(Info.exp_co_ctx, es)), + m, + ); + | Cons(hd, tl) => + let (hd, m) = go(~mode=Mode.of_cons_hd(ctx, mode), hd, m); + let (tl, m) = go(~mode=Mode.of_cons_tl(ctx, mode, hd.ty), tl, m); add( - ~self=Just(List(ty1)), - ~free=Ctx.union([free1, free2]), - union_m([m1, m2]), + ~self=Just(List(hd.ty)), + ~co_ctx=CoCtx.union([hd.co_ctx, tl.co_ctx]), + m, ); | Var(name) => - switch (Ctx.lookup_var(ctx, name)) { - | None => atomic(Free(Variable)) - | Some(var) => - add( - ~self=Just(var.typ), - ~free=[(name, [{id: Term.UExp.rep_id(uexp), mode}])], - Id.Map.empty, - ) - } + add'( + ~self=Self.of_exp_var(ctx, name), + ~co_ctx=CoCtx.singleton(name, UExp.rep_id(uexp), Mode.ty_of(mode)), + m, + ) | Parens(e) => - let (ty, free, m) = go(~mode, e); - add(~self=Just(ty), ~free, m); + let (e, m) = go(~mode, e, m); + add(~self=Just(e.ty), ~co_ctx=e.co_ctx, m); | UnOp(op, e) => let (ty_in, ty_out) = typ_exp_unop(op); - let (_, free, m) = go(~mode=Ana(ty_in), e); - add(~self=Just(ty_out), ~free, m); + let (e, m) = go(~mode=Ana(ty_in), e, m); + add(~self=Just(ty_out), ~co_ctx=e.co_ctx, m); | BinOp(op, e1, e2) => let (ty1, ty2, ty_out) = typ_exp_binop(op); - let (_, free1, m1) = go(~mode=Ana(ty1), e1); - let (_, free2, m2) = go(~mode=Ana(ty2), e2); - add( - ~self=Just(ty_out), - ~free=Ctx.union([free1, free2]), - union_m([m1, m2]), - ); + let (e1, m) = go(~mode=Ana(ty1), e1, m); + let (e2, m) = go(~mode=Ana(ty2), e2, m); + add(~self=Just(ty_out), ~co_ctx=CoCtx.union([e1.co_ctx, e2.co_ctx]), m); | Tuple(es) => - let modes = Typ.matched_prod_mode(mode, List.length(es)); - let infos = List.map2((e, mode) => go(~mode, e), es, modes); - let free = Ctx.union(List.map(((_, f, _)) => f, infos)); - let self = Typ.Just(Prod(List.map(((ty, _, _)) => ty, infos))); - let m = union_m(List.map(((_, _, m)) => m, infos)); - add(~self, ~free, m); - | Tag(name) => - switch (BuiltinADTs.get_tag_typ(name)) { - | None => atomic(Free(Tag)) - | Some(typ) => atomic(Just(typ)) - } - | Test(test) => - let (_, free_test, m1) = go(~mode=Ana(Bool), test); - add(~self=Just(Prod([])), ~free=free_test, m1); - | If(cond, e1, e2) => - let (_, free_e0, m1) = go(~mode=Ana(Bool), cond); - let (ty_e1, free_e1, m2) = go(~mode, e1); - let (ty_e2, free_e2, m3) = go(~mode, e2); + let modes = Mode.of_prod(ctx, mode, List.length(es)); + let (es, m) = map_m_go(m, modes, es); add( - ~self= - Joined( - Fun.id, - [ - {id: Term.UExp.rep_id(e1), ty: ty_e1}, - {id: Term.UExp.rep_id(e2), ty: ty_e2}, - ], - ), - ~free=Ctx.union([free_e0, free_e1, free_e2]), - union_m([m1, m2, m3]), + ~self=Just(Prod(List.map(Info.exp_ty, es))), + ~co_ctx=CoCtx.union(List.map(Info.exp_co_ctx, es)), + m, ); + | Test(e) => + let (e, m) = go(~mode=Ana(Bool), e, m); + add(~self=Just(Prod([])), ~co_ctx=e.co_ctx, m); | Seq(e1, e2) => - let (_, free1, m1) = go(~mode=Syn, e1); - let (ty2, free2, m2) = go(~mode, e2); - add( - ~self=Just(ty2), - ~free=Ctx.union([free1, free2]), - union_m([m1, m2]), - ); + let (e1, m) = go(~mode=Syn, e1, m); + let (e2, m) = go(~mode, e2, m); + add(~self=Just(e2.ty), ~co_ctx=CoCtx.union([e1.co_ctx, e2.co_ctx]), m); + | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr)) | Ap(fn, arg) => - /* Function position mode Ana(Hole->Hole) instead of Syn */ - let (ty_fn, free_fn, m_fn) = - uexp_to_info_map(~ctx, ~mode=Typ.ap_mode, fn); - let (ty_in, ty_out) = Typ.matched_arrow(ty_fn); - let (_, free_arg, m_arg) = - uexp_to_info_map(~ctx, ~mode=Ana(ty_in), arg); + let fn_mode = Mode.of_ap(ctx, mode, UExp.ctr_name(fn)); + let (fn, m) = go(~mode=fn_mode, fn, m); + let (ty_in, ty_out) = Typ.matched_arrow(fn.ty); + let (arg, m) = go(~mode=Ana(ty_in), arg, m); add( ~self=Just(ty_out), - ~free=Ctx.union([free_fn, free_arg]), - union_m([m_fn, m_arg]), + ~co_ctx=CoCtx.union([fn.co_ctx, arg.co_ctx]), + m, ); - | Fun(pat, body) => - let (mode_pat, mode_body) = Typ.matched_arrow_mode(mode); - let (ty_pat, ctx_pat, m_pat) = - upat_to_info_map(~is_synswitch=false, ~mode=mode_pat, pat); - let ctx_body = VarMap.concat(ctx, ctx_pat); - let (ty_body, free_body, m_body) = - uexp_to_info_map(~ctx=ctx_body, ~mode=mode_body, body); + | Fun(p, e) => + let (mode_pat, mode_body) = Mode.of_arrow(ctx, mode); + let (p, m) = go_pat(~is_synswitch=false, ~mode=mode_pat, p, m); + let (e, m) = go'(~ctx=p.ctx, ~mode=mode_body, e, m); add( - ~self=Just(Arrow(ty_pat, ty_body)), - ~free=Ctx.subtract_typ(ctx_pat, free_body), - union_m([m_pat, m_body]), + ~self=Just(Arrow(p.ty, e.ty)), + ~co_ctx=CoCtx.mk(ctx, p.ctx, e.co_ctx), + m, ); - | Let(pat, def, body) => - let (ty_pat, ctx_pat, _m_pat) = - upat_to_info_map(~is_synswitch=true, ~mode=Syn, pat); - let def_ctx = extend_let_def_ctx(ctx, pat, ctx_pat, def); - let (ty_def, free_def, m_def) = - uexp_to_info_map(~ctx=def_ctx, ~mode=Ana(ty_pat), def); + | Let(p, def, body) => + let (p_syn, _) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); + let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); + let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); /* Analyze pattern to incorporate def type into ctx */ - let (_, ctx_pat_ana, m_pat) = - upat_to_info_map(~is_synswitch=false, ~mode=Ana(ty_def), pat); - let ctx_body = VarMap.concat(ctx, ctx_pat_ana); - let (ty_body, free_body, m_body) = - uexp_to_info_map(~ctx=ctx_body, ~mode, body); + let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); + let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); + add( + ~self=Just(body.ty), + ~co_ctx= + CoCtx.union([def.co_ctx, CoCtx.mk(ctx, p_ana.ctx, body.co_ctx)]), + m, + ); + | If(e0, e1, e2) => + let branch_ids = List.map(UExp.rep_id, [e1, e2]); + let (cond, m) = go(~mode=Ana(Bool), e0, m); + let (cons, m) = go(~mode, e1, m); + let (alt, m) = go(~mode, e2, m); add( - ~self=Just(ty_body), - ~free=Ctx.union([free_def, Ctx.subtract_typ(ctx_pat_ana, free_body)]), - union_m([m_pat, m_def, m_body]), + ~self=Self.join(Fun.id, [cons.ty, alt.ty], branch_ids, ctx), + ~co_ctx=CoCtx.union([cond.co_ctx, cons.co_ctx, alt.co_ctx]), + m, ); | Match(scrut, rules) => - let (ty_scrut, free_scrut, m_scrut) = go(~mode=Syn, scrut); - let (pats, branches) = List.split(rules); - let pat_infos = - List.map( - upat_to_info_map(~is_synswitch=false, ~mode=Typ.Ana(ty_scrut)), - pats, - ); - let branch_infos = - List.map2( - (branch, (_, ctx_pat, _)) => - uexp_to_info_map(~ctx=VarMap.concat(ctx, ctx_pat), ~mode, branch), - branches, - pat_infos, - ); - let branch_sources = - List.map2( - (e: Term.UExp.t, (ty, _, _)) => Typ.{id: Term.UExp.rep_id(e), ty}, - branches, - branch_infos, + let (scrut, m) = go(~mode=Syn, scrut, m); + let (ps, es) = List.split(rules); + let branch_ids = List.map(UExp.rep_id, es); + let (ps, m) = + map_m(go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), ps, m); + let p_ctxs = List.map(Info.pat_ctx, ps); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, ); - let pat_ms = List.map(((_, _, m)) => m, pat_infos); - let branch_ms = List.map(((_, _, m)) => m, branch_infos); - let branch_frees = List.map(((_, free, _)) => free, branch_infos); - let self = Typ.Joined(Fun.id, branch_sources); - let free = Ctx.union([free_scrut] @ branch_frees); - add(~self, ~free, union_m([m_scrut] @ pat_ms @ branch_ms)); + let e_tys = List.map(Info.exp_ty, es); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + add( + ~self=Self.join(Fun.id, e_tys, branch_ids, ctx), + ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), + m, + ); + | TyAlias(typat, utyp, body) => + let m = utpat_to_info_map(~ctx, ~ancestors, typat, m) |> snd; + switch (typat.term) { + | Var(name) when !Ctx.shadows_typ(ctx, name) => + /* Currently we disallow all type shadowing */ + /* NOTE(andrew): Currently, UTyp.to_typ returns Unknown(TypeHole) + for any type variable reference not in its ctx. So any free variables + in the definition won't be noticed. But we need to check for free + variables to decide whether to make a recursive type or not. So we + tentatively add an abtract type to the ctx, representing the + speculative rec parameter. */ + let (ty_def, ctx_def, ctx_body) = { + let ty_pre = UTyp.to_typ(Ctx.extend_dummy_tvar(ctx, name), utyp); + switch (utyp.term) { + | Sum(_) when List.mem(name, Typ.free_vars(ty_pre)) => + let ty_rec = Typ.Rec("α", Typ.subst(Var("α"), name, ty_pre)); + let ctx_def = + Ctx.extend_alias(ctx, name, UTPat.rep_id(typat), ty_rec); + (ty_rec, ctx_def, ctx_def); + | _ => + let ty = UTyp.to_typ(ctx, utyp); + (ty, ctx, Ctx.extend_alias(ctx, name, UTPat.rep_id(typat), ty)); + }; + }; + let ctx_body = + switch (Typ.get_sum_constructors(ctx, ty_def)) { + | Some(sm) => Ctx.add_ctrs(ctx_body, name, UTyp.rep_id(utyp), sm) + | None => ctx_body + }; + let (Info.{co_ctx, ty: ty_body, _}, m) = + go'(~ctx=ctx_body, ~mode, body, m); + /* Make sure types don't escape their scope */ + let ty_escape = Typ.subst(ty_def, name, ty_body); + let m = utyp_to_info_map(~ctx=ctx_def, ~ancestors, utyp, m) |> snd; + add(~self=Just(ty_escape), ~co_ctx, m); + | Var(_) + | Invalid(_) + | EmptyHole + | MultiHole(_) => + let (Info.{co_ctx, ty: ty_body, _}, m) = go'(~ctx, ~mode, body, m); + let m = utyp_to_info_map(~ctx, ~ancestors, utyp, m) |> snd; + add(~self=Just(ty_body), ~co_ctx, m); + }; }; } and upat_to_info_map = ( ~is_synswitch, - ~ctx=Ctx.empty, - ~mode: Typ.mode=Typ.Syn, - {ids, term} as upat: Term.UPat.t, + ~ctx, + ~ancestors: Info.ancestors, + ~mode: Mode.t=Mode.Syn, + {ids, term} as upat: UPat.t, + m: Map.t, ) - : (Typ.t, Ctx.t, map) => { - let upat_to_info_map = upat_to_info_map(~is_synswitch); + : (Info.pat, Map.t) => { + let add = (~self, ~ctx, m) => { + let info = + Info.derived_pat(~upat, ~ctx, ~mode, ~ancestors, ~self=Common(self)); + (info, add_info(ids, InfoPat(info), m)); + }; + let atomic = self => add(~self, ~ctx, m); + let ancestors = [UPat.rep_id(upat)] @ ancestors; + let go = upat_to_info_map(~is_synswitch, ~ancestors); let unknown = Typ.Unknown(is_synswitch ? SynSwitch : Internal); - let cls = Term.UPat.cls_of_term(term); - let add = (~self, ~ctx, m) => ( - typ_after_fix(mode, self), - ctx, - add_info(ids, InfoPat({cls, self, mode, ctx, term: upat}), m), - ); - let atomic = self => add(~self, ~ctx, Id.Map.empty); + let ctx_fold = (ctx: Ctx.t, m) => + List.fold_left2( + ((ctx, tys, m), e, mode) => + go(~ctx, ~mode, e, m) + |> (((info, m)) => (info.ctx, tys @ [info.ty], m)), + (ctx, [], m), + ); switch (term) { - | Invalid(msg) => ( - Unknown(Internal), - ctx, - add_info(ids, Invalid(msg), Id.Map.empty), - ) | MultiHole(tms) => - let (_, maps) = tms |> List.map(any_to_info_map(~ctx)) |> List.split; - add(~self=Multi, ~ctx, union_m(maps)); + let (_, m) = multi(~ctx, ~ancestors, m, tms); + add(~self=IsMulti, ~ctx, m); + | Invalid(token) => atomic(BadToken(token)) | EmptyHole => atomic(Just(unknown)) | Int(_) => atomic(Just(Int)) | Float(_) => atomic(Just(Float)) @@ -522,141 +358,160 @@ and upat_to_info_map = | String(_) => atomic(Just(String)) | ListLit([]) => atomic(Just(List(Unknown(Internal)))) | ListLit(ps) => - let modes = List.init(List.length(ps), _ => Typ.matched_list_mode(mode)); - let p_ids = List.map(Term.UPat.rep_id, ps); - let (ctx, infos) = - List.fold_left2( - ((ctx, infos), e, mode) => { - let (_, ctx, _) as info = upat_to_info_map(~ctx, ~mode, e); - (ctx, infos @ [info]); - }, - (ctx, []), - ps, - modes, - ); - let tys = List.map(((ty, _, _)) => ty, infos); - let self: Typ.self = - switch (Typ.join_all(tys)) { - | None => - Joined( - ty => List(ty), - List.map2((id, ty) => Typ.{id, ty}, p_ids, tys), - ) - | Some(ty) => Just(List(ty)) - }; - let info: t = InfoPat({cls, self, mode, ctx, term: upat}); - let m = union_m(List.map(((_, _, m)) => m, infos)); - /* Add an entry for the id of each comma tile */ - let m = List.fold_left((m, id) => Id.Map.add(id, info, m), m, ids); - (typ_after_fix(mode, self), ctx, m); + let modes = Mode.of_list_lit(ctx, List.length(ps), mode); + let (ctx, tys, m) = ctx_fold(ctx, m, ps, modes); + add( + ~self=Self.join(ty => List(ty), tys, List.map(UPat.rep_id, ps), ctx), + ~ctx, + m, + ); | Cons(hd, tl) => - let mode_e = Typ.matched_list_mode(mode); - let (ty1, ctx, m_hd) = upat_to_info_map(~ctx, ~mode=mode_e, hd); - let (_, ctx, m_tl) = upat_to_info_map(~ctx, ~mode=Ana(List(ty1)), tl); - add(~self=Just(List(ty1)), ~ctx, union_m([m_hd, m_tl])); - | Tag(name) => - switch (BuiltinADTs.get_tag_typ(name)) { - | None => atomic(Free(Tag)) - | Some(typ) => atomic(Just(typ)) - } + let (hd, m) = go(~ctx, ~mode=Mode.of_cons_hd(ctx, mode), hd, m); + let (tl, m) = + go(~ctx=hd.ctx, ~mode=Mode.of_cons_tl(ctx, mode, hd.ty), tl, m); + add(~self=Just(List(hd.ty)), ~ctx=tl.ctx, m); | Wild => atomic(Just(unknown)) | Var(name) => - let typ = typ_after_fix(mode, Just(Unknown(Internal))); - let entry = Ctx.VarEntry({name, id: Term.UPat.rep_id(upat), typ}); - add(~self=Just(unknown), ~ctx=Ctx.extend(entry, ctx), Id.Map.empty); + /* NOTE: The self type assigned to pattern variables (Unknown) + may be SynSwitch, but SynSwitch is never added to the context; + Unknown(Internal) is used in this case */ + let ctx_typ = + Info.fixed_typ_pat(ctx, mode, Common(Just(Unknown(Internal)))); + let entry = Ctx.VarEntry({name, id: UPat.rep_id(upat), typ: ctx_typ}); + add(~self=Just(unknown), ~ctx=Ctx.extend(ctx, entry), m); | Tuple(ps) => - let modes = Typ.matched_prod_mode(mode, List.length(ps)); - let (ctx, infos) = - List.fold_left2( - ((ctx, infos), e, mode) => { - let (_, ctx, _) as info = upat_to_info_map(~mode, ~ctx, e); - (ctx, infos @ [info]); - }, - (ctx, []), - ps, - modes, - ); - let self = Typ.Just(Prod(List.map(((ty, _, _)) => ty, infos))); - let m = union_m(List.map(((_, _, m)) => m, infos)); - add(~self, ~ctx, m); + let modes = Mode.of_prod(ctx, mode, List.length(ps)); + let (ctx, tys, m) = ctx_fold(ctx, m, ps, modes); + add(~self=Just(Prod(tys)), ~ctx, m); | Parens(p) => - let (ty, ctx, m) = upat_to_info_map(~ctx, ~mode, p); - add(~self=Just(ty), ~ctx, m); + let (p, m) = go(~ctx, ~mode, p, m); + add(~self=Just(p.ty), ~ctx=p.ctx, m); + | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr)) | Ap(fn, arg) => - /* Contructor application */ - /* Function position mode Ana(Hole->Hole) instead of Syn */ - let (ty_fn, ctx, m_fn) = upat_to_info_map(~ctx, ~mode=Typ.ap_mode, fn); - let (ty_in, ty_out) = Typ.matched_arrow(ty_fn); - let (_, ctx, m_arg) = upat_to_info_map(~ctx, ~mode=Ana(ty_in), arg); - add(~self=Just(ty_out), ~ctx, union_m([m_fn, m_arg])); - | TypeAnn(p, ty) => - let (ty_ann, m_typ) = utyp_to_info_map(ty); - let (_ty, ctx, m) = upat_to_info_map(~ctx, ~mode=Ana(ty_ann), p); - add(~self=Just(ty_ann), ~ctx, union_m([m, m_typ])); + let fn_mode = Mode.of_ap(ctx, mode, UPat.ctr_name(fn)); + let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); + let (ty_in, ty_out) = Typ.matched_arrow(fn.ty); + let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); + add(~self=Just(ty_out), ~ctx=arg.ctx, m); + | TypeAnn(p, ann) => + let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); + let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); + add(~self=Just(ann.ty), ~ctx=p.ctx, m); }; } -and utyp_to_info_map = ({ids, term} as utyp: Term.UTyp.t): (Typ.t, map) => { - let cls = Term.UTyp.cls_of_term(term); - let ty = Term.utyp_to_ty(utyp); - let add = self => add_info(ids, InfoTyp({cls, self, term: utyp})); - let just = m => (ty, add(Just(ty), m)); - switch (term) { - | Invalid(msg) => ( - Unknown(Internal), - add_info(ids, Invalid(msg), Id.Map.empty), +and utyp_to_info_map = + ( + ~ctx, + ~expects=Info.TypeExpected, + ~ancestors, + {ids, term} as utyp: UTyp.t, + m: Map.t, ) + : (Info.typ, Map.t) => { + let add = m => { + let info = Info.derived_typ(~utyp, ~ctx, ~ancestors, ~expects); + (info, add_info(ids, InfoTyp(info), m)); + }; + let ancestors = [UTyp.rep_id(utyp)] @ ancestors; + let go' = utyp_to_info_map(~ctx, ~ancestors); + let go = go'(~expects=TypeExpected); + //TODO(andrew): make this return free, replacing Typ.free_vars + switch (term) { + | MultiHole(tms) => + let (_, m) = multi(~ctx, ~ancestors, m, tms); + add(m); + | Invalid(_) | EmptyHole | Int | Float | Bool - | String => just(Id.Map.empty) + | String => add(m) + | Var(_) + | Constructor(_) => + /* Names are resolved in Info.status_typ */ + add(m) | List(t) - | Parens(t) => - let (_, m) = utyp_to_info_map(t); - just(m); + | Parens(t) => add(go(t, m) |> snd) | Arrow(t1, t2) => - let (_, m_t1) = utyp_to_info_map(t1); - let (_, m_t2) = utyp_to_info_map(t2); - just(union_m([m_t1, m_t2])); + let m = go(t1, m) |> snd; + let m = go(t2, m) |> snd; + add(m); | Tuple(ts) => - let m = ts |> List.map(utyp_to_info_map) |> List.map(snd) |> union_m; - just(m); - | Var(name) => - switch (BuiltinADTs.is_typ_var(name)) { - | None => (Unknown(Internal), add(Free(TypeVariable), Id.Map.empty)) - | Some(_) => (Var(name), add(Just(Var(name)), Id.Map.empty)) - } + let m = map_m(go, ts, m) |> snd; + add(m); + | Ap(t1, t2) => + let ty_in = UTyp.to_typ(ctx, t2); + let t1_mode: Info.typ_expects = + switch (expects) { + | VariantExpected(m, sum_ty) => + ConstructorExpected(m, Arrow(ty_in, sum_ty)) + | _ => ConstructorExpected(Unique, Arrow(ty_in, Unknown(Internal))) + }; + let m = go'(~expects=t1_mode, t1, m) |> snd; + let m = go'(~expects=TypeExpected, t2, m) |> snd; + add(m); + | Sum(variants) => + let ty_sum = UTyp.to_typ(ctx, utyp); + let (m, _) = + List.fold_left( + variant_to_info_map(~ctx, ~ancestors, ~ty_sum), + (m, []), + variants, + ); + add(m); + }; +} +and utpat_to_info_map = + (~ctx, ~ancestors, {ids, term} as utpat: UTPat.t, m: Map.t) + : (Info.tpat, Map.t) => { + let add = m => { + let info = Info.derived_tpat(~utpat, ~ctx, ~ancestors); + (info, add_info(ids, InfoTPat(info), m)); + }; + let ancestors = [UTPat.rep_id(utpat)] @ ancestors; + switch (term) { | MultiHole(tms) => - // TODO thread ctx through to multihole terms once ctx is available - let (_, maps) = - tms |> List.map(any_to_info_map(~ctx=Ctx.empty)) |> List.split; - just(union_m(maps)); + let (_, m) = multi(~ctx, ~ancestors, m, tms); + add(m); + | Invalid(_) + | EmptyHole + | Var(_) => add(m) + }; +} +and variant_to_info_map = + (~ctx, ~ancestors, ~ty_sum, (m, ctrs), uty: UTyp.variant) => { + let go = expects => utyp_to_info_map(~ctx, ~ancestors, ~expects); + switch (uty) { + | BadEntry(uty) => + let m = go(VariantExpected(Unique, ty_sum), uty, m) |> snd; + (m, ctrs); + | Variant(ctr, ids, param) => + let m = + go( + ConstructorExpected( + List.mem(ctr, ctrs) ? Duplicate : Unique, + ty_sum, + ), + {term: Constructor(ctr), ids}, + m, + ) + |> snd; + let m = + switch (param) { + | Some(param_ty) => go(TypeExpected, param_ty, m) |> snd + | None => m + }; + (m, [ctr, ...ctrs]); }; }; let mk_map = - Core.Memo.general( - ~cache_size_bound=1000, - e => { - let (_, _, map) = - uexp_to_info_map(~ctx=Builtins.ctx(Builtins.Pervasives.builtins), e); - map; - }, - ); - -let get_binding_site = (id: Id.t, statics_map: map): option(Id.t) => { - open OptUtil.Syntax; - let* opt = Id.Map.find_opt(id, statics_map); - let* info_exp = - switch (opt) { - | InfoExp(info_exp) => Some(info_exp) - | _ => None - }; - - let+ entry = - switch (info_exp.term.term) { - | TermBase.UExp.Var(name) => Ctx.lookup_var(info_exp.ctx, name) - | _ => None - }; - entry.id; -}; + Core.Memo.general(~cache_size_bound=1000, e => { + uexp_to_info_map( + ~ctx=Builtins.ctx(Builtins.Pervasives.builtins), + ~ancestors=[], + e, + Id.Map.empty, + ) + |> snd + }); diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 81297af417..377650975e 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -19,7 +19,6 @@ include TermBase.Any; type any = t; - module UTyp = { [@deriving (show({with_path: false}), sexp, yojson)] type cls = @@ -32,9 +31,12 @@ module UTyp = { | String | Arrow | Tuple + | Sum | List | Var - | Parens; + | Constructor + | Parens + | Ap; include TermBase.UTyp; @@ -61,23 +63,29 @@ module UTyp = { | List(_) => List | Arrow(_) => Arrow | Var(_) => Var + | Constructor(_) => Constructor | Tuple(_) => Tuple - | Parens(_) => Parens; + | Parens(_) => Parens + | Ap(_) => Ap + | Sum(_) => Sum; let show_cls: cls => string = fun - | Invalid => "Invalid Type" - | EmptyHole => "Empty Type Hole" - | MultiHole => "Multi Type Hole" + | Invalid => "Invalid type" + | MultiHole => "Broken type" + | EmptyHole => "Empty type hole" | Int | Float | String - | Bool => "Base Type" - | Var => "Type Variable" - | List => "List Type" - | Arrow => "Function Type" - | Tuple => "Product Type" - | Parens => "Parenthesized Type Term"; + | Bool => "Base type" + | Var => "Type variable" + | Constructor => "Sum constructor" + | List => "List type" + | Arrow => "Function type" + | Tuple => "Product type" + | Sum => "Sum type" + | Parens => "Parenthesized type" + | Ap => "Constructor application"; let rec is_arrow = (typ: t) => { switch (typ.term) { @@ -92,9 +100,89 @@ module UTyp = { | String | List(_) | Tuple(_) - | Var(_) => false + | Var(_) + | Constructor(_) + | Ap(_) + | Sum(_) => false }; }; + + /* Converts a syntactic type into a semantic type */ + let rec to_typ: (Ctx.t, t) => Typ.t = + (ctx, utyp) => + switch (utyp.term) { + | Invalid(_) + | MultiHole(_) => Unknown(Internal) + | EmptyHole => Unknown(TypeHole) + | Bool => Bool + | Int => Int + | Float => Float + | String => String + | Var(name) => + switch (Ctx.lookup_tvar(ctx, name)) { + | Some(_) => Var(name) + | None => Unknown(Free(name)) + } + | Arrow(u1, u2) => Arrow(to_typ(ctx, u1), to_typ(ctx, u2)) + | Tuple(us) => Prod(List.map(to_typ(ctx), us)) + | Sum(uts) => Sum(to_ctr_map(ctx, uts)) + | List(u) => List(to_typ(ctx, u)) + | Parens(u) => to_typ(ctx, u) + /* The below cases should occur only inside sums */ + | Constructor(_) + | Ap(_) => Unknown(Internal) + } + and to_variant: + (Ctx.t, variant) => option(ConstructorMap.binding(option(Typ.t))) = + ctx => + fun + | Variant(ctr, _, u) => Some((ctr, Option.map(to_typ(ctx), u))) + | BadEntry(_) => None + and to_ctr_map = (ctx: Ctx.t, uts: list(variant)): Typ.sum_map => { + List.fold_left( + (acc, ut) => + List.find_opt(((ctr, _)) => ctr == fst(ut), acc) == None + ? acc @ [ut] : acc, + [], + List.filter_map(to_variant(ctx), uts), + ); + }; +}; + +module UTPat = { + [@deriving (show({with_path: false}), sexp, yojson)] + type cls = + | Invalid + | EmptyHole + | MultiHole + | Var; + + include TermBase.UTPat; + + let rep_id = ({ids, _}) => { + assert(ids != []); + List.hd(ids); + }; + + let hole = (tms: list(any)) => + switch (tms) { + | [] => EmptyHole + | [_, ..._] => MultiHole(tms) + }; + + let cls_of_term: term => cls = + fun + | Invalid(_) => Invalid + | EmptyHole => EmptyHole + | MultiHole(_) => MultiHole + | Var(_) => Var; + + let show_cls: cls => string = + fun + | Invalid => "Invalid type alias" + | MultiHole => "Broken type alias" + | EmptyHole => "Empty type alias hole" + | Var => "Type alias"; }; module UPat = { @@ -110,7 +198,7 @@ module UPat = { | String | Triv | ListLit - | Tag + | Constructor | Cons | Var | Tuple @@ -143,7 +231,7 @@ module UPat = { | String(_) => String | Triv => Triv | ListLit(_) => ListLit - | Tag(_) => Tag + | Constructor(_) => Constructor | Cons(_) => Cons | Var(_) => Var | Tuple(_) => Tuple @@ -153,23 +241,23 @@ module UPat = { let show_cls: cls => string = fun - | Invalid => "Invalid Pattern" - | EmptyHole => "Empty Pattern Hole" - | MultiHole => "Multi Pattern Hole" - | Wild => "Wildcard Pattern" - | Int => "Integer Literal" - | Float => "Float Literal" - | Bool => "Boolean Literal" - | String => "String Literal" - | Triv => "Trivial Literal. Pathetic, really." - | ListLit => "List Literal Pattern" - | Tag => "Constructor Pattern" - | Cons => "List Cons" - | Var => "Pattern Variable" - | Tuple => "Tuple Pattern" - | Parens => "Parenthesized Pattern" - | Ap => "Constructor Application" - | TypeAnn => "Type Annotation"; + | Invalid => "Invalid pattern" + | MultiHole => "Broken pattern" + | EmptyHole => "Empty pattern hole" + | Wild => "Wildcard" + | Int => "Integer literal" + | Float => "Float literal" + | Bool => "Boolean literal" + | String => "String literal" + | Triv => "Trivial literal" + | ListLit => "List literal" + | Constructor => "Constructor" + | Cons => "Cons" + | Var => "New variable" + | Tuple => "Tuple" + | Parens => "Parenthesized pattern" + | Ap => "Constructor application" + | TypeAnn => "Annotation"; let rec is_var = (pat: t) => { switch (pat.term) { @@ -188,7 +276,7 @@ module UPat = { | ListLit(_) | Cons(_, _) | Tuple(_) - | Tag(_) + | Constructor(_) | Ap(_) => false }; }; @@ -210,7 +298,7 @@ module UPat = { | Cons(_, _) | Var(_) | Tuple(_) - | Tag(_) + | Constructor(_) | Ap(_) => false }; }; @@ -234,7 +322,7 @@ module UPat = { | Cons(_, _) | Var(_) | TypeAnn(_) - | Tag(_) + | Constructor(_) | Ap(_) => false } ); @@ -256,7 +344,7 @@ module UPat = { | ListLit(_) | Cons(_, _) | Tuple(_) - | Tag(_) + | Constructor(_) | Ap(_) => None }; }; @@ -283,7 +371,7 @@ module UPat = { | Cons(_, _) | Var(_) | Tuple(_) - | Tag(_) + | Constructor(_) | Ap(_) => None }; }; @@ -314,17 +402,50 @@ module UPat = { | Cons(_, _) | Var(_) | TypeAnn(_) - | Tag(_) + | Constructor(_) | Ap(_) => None } }; }; + + let ctr_name = (p: t): option(Constructor.t) => + switch (p.term) { + | Constructor(name) => Some(name) + | _ => None + }; }; module UExp = { include TermBase.UExp; - let hole = (tms: list(any)) => + [@deriving (show({with_path: false}), sexp, yojson)] + type cls = + | Invalid + | EmptyHole + | MultiHole + | Triv + | Bool + | Int + | Float + | String + | ListLit + | Constructor + | Fun + | Tuple + | Var + | Let + | TyAlias + | Ap + | If + | Seq + | Test + | Parens + | Cons + | UnOp(op_un) + | BinOp(op_bin) + | Match; + + let hole = (tms: list(any)): term => switch (tms) { | [] => EmptyHole | [_, ..._] => MultiHole(tms) @@ -346,11 +467,12 @@ module UExp = { | Float(_) => Float | String(_) => String | ListLit(_) => ListLit - | Tag(_) => Tag + | Constructor(_) => Constructor | Fun(_) => Fun | Tuple(_) => Tuple | Var(_) => Var | Let(_) => Let + | TyAlias(_) => TyAlias | Ap(_) => Ap | If(_) => If | Seq(_) => Seq @@ -413,29 +535,30 @@ module UExp = { let show_cls: cls => string = fun - | Invalid => "Invalid Expression" - | EmptyHole => "Empty Expression Hole" - | MultiHole => "Multi Expression Hole" - | Triv => "Trivial Literal. Pathetic, really." - | Bool => "Boolean Literal" - | Int => "Integer Literal" - | Float => "Float Literal" - | String => "String Literal" - | ListLit => "List Literal" - | Tag => "Constructor" - | Fun => "Function Literal" - | Tuple => "Tuple Literal" - | Var => "Variable Reference" - | Let => "Let Expression" - | Ap => "Function/Contructor Application" - | If => "If Expression" - | Seq => "Sequence Expression" - | Test => "Test (Effectful)" - | Parens => "Parenthesized Expression" + | Invalid => "Invalid expression" + | MultiHole => "Broken expression" + | EmptyHole => "Empty expression hole" + | Triv => "Trivial litera" + | Bool => "Boolean literal" + | Int => "Integer literal" + | Float => "Float literal" + | String => "String literal" + | ListLit => "List literal" + | Constructor => "Constructor" + | Fun => "Function literal" + | Tuple => "Tuple literal" + | Var => "Variable reference" + | Let => "Let expression" + | TyAlias => "Type Alias definition" + | Ap => "Application" + | If => "If expression" + | Seq => "Sequence expression" + | Test => "Test" + | Parens => "Parenthesized expression" | Cons => "Cons" | BinOp(op) => show_binop(op) | UnOp(op) => show_unop(op) - | Match => "Match Expression"; + | Match => "Case expression"; let rec is_fun = (e: t) => { switch (e.term) { @@ -453,6 +576,7 @@ module UExp = { | Tuple(_) | Var(_) | Let(_) + | TyAlias(_) | Ap(_) | If(_) | Seq(_) @@ -461,7 +585,7 @@ module UExp = { | UnOp(_) | BinOp(_) | Match(_) - | Tag(_) => false + | Constructor(_) => false }; }; @@ -483,6 +607,7 @@ module UExp = { | Fun(_) | Var(_) | Let(_) + | TyAlias(_) | Ap(_) | If(_) | Seq(_) @@ -491,28 +616,16 @@ module UExp = { | UnOp(_) | BinOp(_) | Match(_) - | Tag(_) => false + | Constructor(_) => false } ); -}; -/* Converts a syntactic type into a semantic type */ -let rec utyp_to_ty: UTyp.t => Typ.t = - utyp => - switch (utyp.term) { - | Invalid(_) - | MultiHole(_) => Unknown(Internal) - | EmptyHole => Unknown(TypeHole) - | Bool => Bool - | Int => Int - | Float => Float - | String => String - | Var(name) => Var(name) - | Arrow(u1, u2) => Arrow(utyp_to_ty(u1), utyp_to_ty(u2)) - | Tuple(us) => Prod(List.map(utyp_to_ty, us)) - | List(u) => List(utyp_to_ty(u)) - | Parens(u) => utyp_to_ty(u) + let ctr_name = (e: t): option(Constructor.t) => + switch (e.term) { + | Constructor(name) => Some(name) + | _ => None }; +}; // TODO(d): consider just folding this into UExp module URul = { @@ -543,11 +656,31 @@ module URul = { }; }; +module Cls = { + [@deriving (show({with_path: false}), sexp, yojson)] + type t = + | Exp(UExp.cls) + | Pat(UPat.cls) + | Typ(UTyp.cls) + | TPat(UTPat.cls) + | Rul(URul.cls); + + let show = (cls: t) => + switch (cls) { + | Exp(cls) => UExp.show_cls(cls) + | Pat(cls) => UPat.show_cls(cls) + | Typ(cls) => UTyp.show_cls(cls) + | TPat(cls) => UTPat.show_cls(cls) + | Rul(cls) => URul.show_cls(cls) + }; +}; + let rec ids = fun | Exp(tm) => tm.ids | Pat(tm) => tm.ids | Typ(tm) => tm.ids + | TPat(tm) => tm.ids | Rul(tm) => URul.ids(~any_ids=ids, tm) | Nul () | Any () => []; @@ -568,6 +701,7 @@ let rep_id = | Exp(tm) => UExp.rep_id(tm) | Pat(tm) => UPat.rep_id(tm) | Typ(tm) => UTyp.rep_id(tm) + | TPat(tm) => UTPat.rep_id(tm) | Rul(tm) => URul.rep_id(~any_ids=ids, tm) | Nul () | Any () => raise(Invalid_argument("Term.rep_id")); diff --git a/src/haz3lcore/statics/TermBase.re b/src/haz3lcore/statics/TermBase.re index b1e269a7dd..04d583e00d 100644 --- a/src/haz3lcore/statics/TermBase.re +++ b/src/haz3lcore/statics/TermBase.re @@ -1,37 +1,42 @@ open Sexplib.Std; -[@deriving (show({with_path: false}), sexp, yojson)] -type parse_flag = - | Secondary // Not really an error - | MalformedGrout // Should never happen - | UnrecognizedTerm // Reminder to add term to MakeTerm - | IncompleteTile; // Remove in future - -let show_parse_flag: parse_flag => string = - fun - | Secondary => "Secondary" - | MalformedGrout => "Malformed Grout" - | UnrecognizedTerm => "Unrecognized Term" - | IncompleteTile => "Incomplete Tile"; - module rec Any: { [@deriving (show({with_path: false}), sexp, yojson)] type t = | Exp(UExp.t) | Pat(UPat.t) | Typ(UTyp.t) + | TPat(UTPat.t) | Rul(URul.t) | Nul(unit) | Any(unit); + + let is_exp: t => option(UExp.t); + let is_pat: t => option(UPat.t); + let is_typ: t => option(UTyp.t); } = { [@deriving (show({with_path: false}), sexp, yojson)] type t = | Exp(UExp.t) | Pat(UPat.t) | Typ(UTyp.t) + | TPat(UTPat.t) | Rul(URul.t) | Nul(unit) | Any(unit); + + let is_exp: t => option(UExp.t) = + fun + | Exp(e) => Some(e) + | _ => None; + let is_pat: t => option(UPat.t) = + fun + | Pat(p) => Some(p) + | _ => None; + let is_typ: t => option(UTyp.t) = + fun + | Typ(t) => Some(t) + | _ => None; } and UExp: { [@deriving (show({with_path: false}), sexp, yojson)] @@ -84,35 +89,9 @@ and UExp: { | Bool(op_bin_bool) | String(op_bin_string); - [@deriving (show({with_path: false}), sexp, yojson)] - type cls = - | Invalid - | EmptyHole - | MultiHole - | Triv - | Bool - | Int - | Float - | String - | ListLit - | Tag - | Fun - | Tuple - | Var - | Let - | Ap - | If - | Seq - | Test - | Parens - | Cons - | UnOp(op_un) - | BinOp(op_bin) - | Match; - [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Triv @@ -121,12 +100,12 @@ and UExp: { | Float(float) | String(string) | ListLit(list(t)) - | Tag(string) + | Constructor(string) | Fun(UPat.t, t) | Tuple(list(t)) - | Var(Token.t) + | Var(Var.t) | Let(UPat.t, t, t) - // Let_pat(UPat.t, t) + | TyAlias(UTPat.t, UTyp.t, t) | Ap(t, t) | If(t, t, t) | Seq(t, t) @@ -192,35 +171,9 @@ and UExp: { | Bool(op_bin_bool) | String(op_bin_string); - [@deriving (show({with_path: false}), sexp, yojson)] - type cls = - | Invalid - | EmptyHole - | MultiHole - | Triv - | Bool - | Int - | Float - | String - | ListLit - | Tag - | Fun - | Tuple - | Var - | Let - | Ap - | If - | Seq - | Test - | Parens - | Cons - | UnOp(op_un) - | BinOp(op_bin) - | Match; - [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Triv @@ -229,12 +182,12 @@ and UExp: { | Float(float) | String(string) | ListLit(list(t)) - | Tag(string) + | Constructor(string) | Fun(UPat.t, t) | Tuple(list(t)) - | Var(Token.t) + | Var(Var.t) | Let(UPat.t, t, t) - // Let_pat(UPat.t, t) + | TyAlias(UTPat.t, UTyp.t, t) | Ap(t, t) | If(t, t, t) | Seq(t, t) @@ -253,7 +206,7 @@ and UExp: { and UPat: { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Wild @@ -263,9 +216,9 @@ and UPat: { | String(string) | Triv | ListLit(list(t)) - | Tag(string) + | Constructor(string) | Cons(t, t) - | Var(Token.t) + | Var(Var.t) | Tuple(list(t)) | Parens(t) | Ap(t, t) @@ -277,7 +230,7 @@ and UPat: { } = { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Wild @@ -287,9 +240,9 @@ and UPat: { | String(string) | Triv | ListLit(list(t)) - | Tag(string) + | Constructor(string) | Cons(t, t) - | Var(Token.t) + | Var(Var.t) | Tuple(list(t)) | Parens(t) | Ap(t, t) @@ -302,7 +255,7 @@ and UPat: { and UTyp: { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Int @@ -311,9 +264,15 @@ and UTyp: { | String | List(t) | Var(string) + | Constructor(string) | Arrow(t, t) | Tuple(list(t)) | Parens(t) + | Ap(t, t) + | Sum(list(variant)) + and variant = + | Variant(Constructor.t, list(Id.t), option(t)) + | BadEntry(t) and t = { ids: list(Id.t), term, @@ -321,7 +280,7 @@ and UTyp: { } = { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | EmptyHole | MultiHole(list(Any.t)) | Int @@ -330,9 +289,38 @@ and UTyp: { | String | List(t) | Var(string) + | Constructor(string) | Arrow(t, t) | Tuple(list(t)) | Parens(t) + | Ap(t, t) + | Sum(list(variant)) + and variant = + | Variant(Constructor.t, list(Id.t), option(t)) + | BadEntry(t) + and t = { + ids: list(Id.t), + term, + }; +} +and UTPat: { + [@deriving (show({with_path: false}), sexp, yojson)] + type term = + | Invalid(string) + | EmptyHole + | MultiHole(list(Any.t)) + | Var(TypVar.t) + and t = { + ids: list(Id.t), + term, + }; +} = { + [@deriving (show({with_path: false}), sexp, yojson)] + type term = + | Invalid(string) + | EmptyHole + | MultiHole(list(Any.t)) + | Var(TypVar.t) and t = { ids: list(Id.t), term, @@ -341,7 +329,7 @@ and UTyp: { and URul: { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | Hole(list(Any.t)) | Rules(UExp.t, list((UPat.t, UExp.t))) and t = { @@ -351,7 +339,7 @@ and URul: { } = { [@deriving (show({with_path: false}), sexp, yojson)] type term = - | Invalid(parse_flag) + | Invalid(string) | Hole(list(Any.t)) | Rules(UExp.t, list((UPat.t, UExp.t))) and t = { diff --git a/src/haz3lcore/statics/Typ.re b/src/haz3lcore/statics/Typ.re index e3a139aa13..3c34e25a60 100644 --- a/src/haz3lcore/statics/Typ.re +++ b/src/haz3lcore/statics/Typ.re @@ -1,246 +1 @@ -open Sexplib.Std; - -/* TYPE_PROVENANCE: From whence does an unknown type originate? - Is it generated from an unannotated pattern variable (SynSwitch), - a pattern variable annotated with a type hole (TypeHole), or - generated by an internal judgement (Internal)? */ -[@deriving (show({with_path: false}), sexp, yojson)] -type type_provenance = - | SynSwitch - | TypeHole - | Internal; - -/* TYP.T: Hazel types */ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Unknown(type_provenance) - | Int - | Float - | Bool - | String - | Var(string) - | List(t) - | Arrow(t, t) - | Sum(t, t) // unused - | Prod(list(t)); - -/* SOURCE: Hazel type annotated with a relevant source location. - Currently used to track match branches for inconsistent - branches errors, but could perhaps be used more broadly - for type debugging UI. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type source = { - id: int, - ty: t, -}; - -[@deriving (show({with_path: false}), sexp, yojson)] -type free_errors = - | Variable - | Tag - | TypeVariable; - -/* SELF: The (synthetic) type information derivable from a term - in isolation, using the typing context but not the syntactic - context. This can either be Free (no type, in the case of - unbound/undefined names), Joined (a list of types, possibly - inconsistent, generated by branching forms like ifs, - matches, and list literals), or Just a regular type. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type self = - | Just(t) - // TODO: make it so that joined applies only to inconsistent types; rename NoJoin - | Joined(t => t, list(source)) - | Multi - | Free(free_errors); - -/* MODE: The (analytic) type information derived from a term's - syntactic context. This can either Syn (no type expectation), - or Ana (a type expectation). It is conjectured [citation needed] - that the Syn mode is functionally indistinguishable from - Ana(Unknown(SynSwitch)), and that this type is thus vestigial. */ -[@deriving (show({with_path: false}), sexp, yojson)] -type mode = - | SynFun - | Syn - | Ana(t); - -/* Strip location information from a list of sources */ -let source_tys = List.map((source: source) => source.ty); - -/* How type provenance information should be collated when - joining unknown types. This probably requires more thought, - but right now TypeHole strictly predominates over Internal - which strictly predominates over SynSwitch. */ -let join_type_provenance = - (p1: type_provenance, p2: type_provenance): type_provenance => - switch (p1, p2) { - | (TypeHole, TypeHole | Internal | SynSwitch) - | (Internal | SynSwitch, TypeHole) => TypeHole - | (Internal, Internal | SynSwitch) - | (SynSwitch, Internal) => Internal - | (SynSwitch, SynSwitch) => SynSwitch - }; - -/* Lattice join on types. This is a LUB join in the hazel2 - sense in that any type dominates Unknown */ -let rec join = (ty1: t, ty2: t): option(t) => - switch (ty1, ty2) { - | (Unknown(p1), Unknown(p2)) => - Some(Unknown(join_type_provenance(p1, p2))) - | (Unknown(_), ty) - | (ty, Unknown(_)) => Some(ty) - | (Int, Int) => Some(Int) - | (Int, _) => None - | (Float, Float) => Some(Float) - | (Float, _) => None - | (Bool, Bool) => Some(Bool) - | (Bool, _) => None - | (String, String) => Some(String) - | (String, _) => None - | (Arrow(ty1_1, ty1_2), Arrow(ty2_1, ty2_2)) => - switch (join(ty1_1, ty2_1), join(ty1_2, ty2_2)) { - | (Some(ty1), Some(ty2)) => Some(Arrow(ty1, ty2)) - | _ => None - } - | (Arrow(_), _) => None - | (Prod(tys1), Prod(tys2)) => - if (List.length(tys1) != List.length(tys2)) { - None; - } else { - switch (List.map2(join, tys1, tys2) |> Util.OptUtil.sequence) { - | None => None - | Some(tys) => Some(Prod(tys)) - }; - } - | (Prod(_), _) => None - | (Sum(ty1_1, ty1_2), Sum(ty2_1, ty2_2)) => - switch (join(ty1_1, ty2_1), join(ty1_2, ty2_2)) { - | (Some(ty1), Some(ty2)) => Some(Sum(ty1, ty2)) - | _ => None - } - | (Sum(_), _) => None - | (List(ty_1), List(ty_2)) => - switch (join(ty_1, ty_2)) { - | Some(ty) => Some(List(ty)) - | None => None - } - | (List(_), _) => None - | (Var(n1), Var(n2)) when n1 == n2 => Some(ty1) - | (Var(_), _) => None - }; - -let join_all: list(t) => option(t) = - List.fold_left( - (acc, ty) => Util.OptUtil.and_then(join(ty), acc), - Some(Unknown(Internal)), - ); - -let join_or_fst = (ty: t, ty': t): t => - switch (join(ty, ty')) { - | None => ty - | Some(ty) => ty - }; - -let t_of_self = - fun - | Just(t) => t - | Joined(wrap, ss) => - switch (ss |> List.map(s => s.ty) |> join_all) { - | None => Unknown(Internal) - | Some(t) => wrap(t) - } - | Multi - | Free(_) => Unknown(Internal); - -/* MATCHED JUDGEMENTS: Note that matched judgements work - a bit different than hazel2 here since hole fixing is - implicit. Somebody should check that what I'm doing - here actually makes sense -Andrew */ - -let matched_arrow: t => (t, t) = - fun - | Arrow(ty_in, ty_out) => (ty_in, ty_out) - | Unknown(prov) => (Unknown(prov), Unknown(prov)) - | _ => (Unknown(Internal), Unknown(Internal)); - -let matched_arrow_mode: mode => (mode, mode) = - fun - | SynFun - | Syn => (Syn, Syn) - | Ana(ty) => { - let (ty_in, ty_out) = matched_arrow(ty); - (Ana(ty_in), Ana(ty_out)); - }; - -let matched_prod_mode = (mode: mode, length): list(mode) => - switch (mode) { - | Ana(Prod(ana_tys)) when List.length(ana_tys) == length => - List.map(ty => Ana(ty), ana_tys) - | Ana(Unknown(prod)) => List.init(length, _ => Ana(Unknown(prod))) - | _ => List.init(length, _ => Syn) - }; - -let matched_list: t => t = - fun - | List(ty) => ty - | Unknown(prov) => Unknown(prov) - | _ => Unknown(Internal); - -let matched_list_mode: mode => mode = - fun - | SynFun - | Syn => Syn - | Ana(ty) => Ana(matched_list(ty)); - -let ap_mode: mode = SynFun; - -/* Legacy code from HTyp */ - -let precedence_Prod = 1; -let precedence_Arrow = 2; -let precedence_Sum = 3; -let precedence_const = 4; -let precedence = (ty: t): int => - switch (ty) { - | Int - | Float - | Bool - | String - | Unknown(_) - | Var(_) - | Prod([]) - | List(_) => precedence_const - | Prod(_) => precedence_Prod - | Sum(_, _) => precedence_Sum - | Arrow(_, _) => precedence_Arrow - }; - -/* equality - At the moment, this coincides with default equality, - but this will change when polymorphic types are implemented */ -let rec eq = (t1, t2) => - switch (t1, t2) { - | (Int, Int) => true - | (Int, _) => false - | (Float, Float) => true - | (Float, _) => false - | (Bool, Bool) => true - | (Bool, _) => false - | (String, String) => true - | (String, _) => false - | (Unknown(_), Unknown(_)) => true - | (Unknown(_), _) => false - | (Arrow(t1_1, t1_2), Arrow(t2_1, t2_2)) => - eq(t1_1, t2_1) && eq(t1_2, t2_2) - | (Arrow(_), _) => false - | (Prod(tys1), Prod(tys2)) => - List.length(tys1) == List.length(tys2) && List.for_all2(eq, tys1, tys2) - | (Prod(_), _) => false - | (Sum(t1_1, t1_2), Sum(t2_1, t2_2)) => eq(t1_1, t2_1) && eq(t1_2, t2_2) - | (Sum(_), _) => false - | (List(t1), List(t2)) => eq(t1, t2) - | (List(_), _) => false - | (Var(n1), Var(n2)) => n1 == n2 - | (Var(_), _) => false - }; +include TypBase.Typ; diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re new file mode 100644 index 0000000000..775d177801 --- /dev/null +++ b/src/haz3lcore/statics/TypBase.re @@ -0,0 +1,606 @@ +open Sexplib.Std; +open Util; +open OptUtil.Syntax; + +module rec Typ: { + /* TYPE_PROVENANCE: From whence does an unknown type originate? + Is it generated from an unannotated pattern variable (SynSwitch), + a pattern variable annotated with a type hole (TypeHole), or + generated by an internal judgement (Internal)? */ + [@deriving (show({with_path: false}), sexp, yojson)] + type type_provenance = + | SynSwitch + | TypeHole + | Free(TypVar.t) + | Internal; + + /* TYP.T: Hazel types */ + [@deriving (show({with_path: false}), sexp, yojson)] + type t = + | Unknown(type_provenance) + | Int + | Float + | Bool + | String + | Var(TypVar.t) + | List(t) + | Arrow(t, t) + | Sum(sum_map) + | Prod(list(t)) + | Rec(TypVar.t, t) + and sum_map = ConstructorMap.t(option(t)); + + [@deriving (show({with_path: false}), sexp, yojson)] + type sum_entry = ConstructorMap.binding(option(t)); + + /* Hazel type annotated with a relevant source location. + Currently used to track match branches for inconsistent + branches errors, but could perhaps be used more broadly + for type debugging UI. */ + [@deriving (show({with_path: false}), sexp, yojson)] + type source = { + id: int, + ty: t, + }; + + let of_source: list(source) => list(t); + let join_type_provenance: + (type_provenance, type_provenance) => type_provenance; + let matched_arrow: t => (t, t); + let matched_prod: (int, t) => list(t); + let matched_cons: t => (t, t); + let matched_list: t => t; + let precedence_Prod: int; + let precedence_Arrow: int; + let precedence_Sum: int; + let precedence_const: int; + let precedence: t => int; + let subst: (t, TypVar.t, t) => t; + let unroll: t => t; + let eq: (t, t) => bool; + let free_vars: (~bound: list(Var.t)=?, t) => list(Var.t); + let join: (~resolve: bool=?, ~fix: bool, Ctx.t, t, t) => option(t); + let join_fix: (~resolve: bool=?, Ctx.t, t, t) => option(t); + let join_all: (Ctx.t, list(t)) => option(t); + let weak_head_normalize: (Ctx.t, t) => t; + let normalize: (Ctx.t, t) => t; + let sum_entry: (Constructor.t, sum_map) => option(sum_entry); + let get_sum_constructors: (Ctx.t, t) => option(sum_map); +} = { + [@deriving (show({with_path: false}), sexp, yojson)] + type type_provenance = + | SynSwitch + | TypeHole + | Free(TypVar.t) + | Internal; + + /* TYP.T: Hazel types */ + [@deriving (show({with_path: false}), sexp, yojson)] + type t = + | Unknown(type_provenance) + | Int + | Float + | Bool + | String + | Var(TypVar.t) + | List(t) + | Arrow(t, t) + | Sum(sum_map) + | Prod(list(t)) + | Rec(TypVar.t, t) + and sum_map = ConstructorMap.t(option(t)); + + [@deriving (show({with_path: false}), sexp, yojson)] + type sum_entry = ConstructorMap.binding(option(t)); + + [@deriving (show({with_path: false}), sexp, yojson)] + type source = { + id: int, + ty: t, + }; + + /* Strip location information from a list of sources */ + let of_source = List.map((source: source) => source.ty); + + /* How type provenance information should be collated when + joining unknown types. This probably requires more thought, + but right now TypeHole strictly predominates over Internal + which strictly predominates over SynSwitch. */ + let join_type_provenance = + (p1: type_provenance, p2: type_provenance): type_provenance => + switch (p1, p2) { + | (Free(tv1), Free(tv2)) when TypVar.eq(tv1, tv2) => Free(tv1) + | (Internal | Free(_), _) + | (_, Internal | Free(_)) => Internal + | (TypeHole, TypeHole | SynSwitch) + | (SynSwitch, TypeHole) => TypeHole + | (SynSwitch, SynSwitch) => SynSwitch + }; + + let matched_arrow: t => (t, t) = + fun + | Arrow(ty_in, ty_out) => (ty_in, ty_out) + | Unknown(SynSwitch) => (Unknown(SynSwitch), Unknown(SynSwitch)) + | _ => (Unknown(Internal), Unknown(Internal)); + + let matched_prod: (int, t) => list(t) = + length => + fun + | Prod(tys) when List.length(tys) == length => tys + | Unknown(SynSwitch) => List.init(length, _ => Unknown(SynSwitch)) + | _ => List.init(length, _ => Unknown(Internal)); + + let matched_cons: t => (t, t) = + fun + | List(ty) => (ty, List(ty)) + | Unknown(SynSwitch) => (Unknown(SynSwitch), List(Unknown(SynSwitch))) + | _ => (Unknown(Internal), List(Unknown(SynSwitch))); + + let matched_list: t => t = + fun + | List(ty) => ty + | Unknown(SynSwitch) => Unknown(SynSwitch) + | _ => Unknown(Internal); + + let precedence_Prod = 1; + let precedence_Arrow = 2; + let precedence_Sum = 3; + let precedence_const = 4; + let precedence = (ty: t): int => + switch (ty) { + | Int + | Float + | Bool + | String + | Unknown(_) + | Var(_) + | Rec(_) + | Sum(_) + | List(_) => precedence_const + | Prod(_) => precedence_Prod + | Arrow(_, _) => precedence_Arrow + }; + + let rec subst = (s: t, x: TypVar.t, ty: t) => { + switch (ty) { + | Int => Int + | Float => Float + | Bool => Bool + | String => String + | Unknown(prov) => Unknown(prov) + | Arrow(ty1, ty2) => Arrow(subst(s, x, ty1), subst(s, x, ty2)) + | Prod(tys) => Prod(List.map(subst(s, x), tys)) + | Sum(sm) => Sum(ConstructorMap.map(Option.map(subst(s, x)), sm)) + | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) + | Rec(y, ty) => Rec(y, subst(s, x, ty)) + | List(ty) => List(subst(s, x, ty)) + | Var(y) => TypVar.eq(x, y) ? s : Var(y) + }; + }; + + let unroll = (ty: t): t => + switch (ty) { + | Rec(x, ty_body) => subst(ty, x, ty_body) + | _ => ty + }; + + /* Type Equality: At the moment, this coincides with alpha equivalence, + but this will change when polymorphic types are implemented */ + let rec eq = (t1: t, t2: t): bool => { + switch (t1, t2) { + | (Rec(x1, t1), Rec(x2, t2)) => eq(t1, subst(Var(x1), x2, t2)) + | (Rec(_), _) => false + | (Int, Int) => true + | (Int, _) => false + | (Float, Float) => true + | (Float, _) => false + | (Bool, Bool) => true + | (Bool, _) => false + | (String, String) => true + | (String, _) => false + | (Unknown(_), Unknown(_)) => true + | (Unknown(_), _) => false + | (Arrow(t1, t2), Arrow(t1', t2')) => eq(t1, t1') && eq(t2, t2') + | (Arrow(_), _) => false + | (Prod(tys1), Prod(tys2)) => List.equal(eq, tys1, tys2) + | (Prod(_), _) => false + | (List(t1), List(t2)) => eq(t1, t2) + | (List(_), _) => false + | (Sum(sm1), Sum(sm2)) => + ConstructorMap.equal(Option.equal(eq), sm1, sm2) + | (Sum(_), _) => false + | (Var(n1), Var(n2)) => n1 == n2 + | (Var(_), _) => false + }; + }; + + let rec free_vars = (~bound=[], ty: t): list(Var.t) => + switch (ty) { + | Unknown(_) + | Int + | Float + | Bool + | String => [] + | Var(v) => List.mem(v, bound) ? [] : [v] + | List(ty) => free_vars(~bound, ty) + | Arrow(t1, t2) => free_vars(~bound, t1) @ free_vars(~bound, t2) + | Sum(sm) => + ListUtil.flat_map( + fun + | None => [] + | Some(typ) => free_vars(~bound, typ), + List.map(snd, sm), + ) + | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) + | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) + }; + + /* Lattice join on types. This is a LUB join in the hazel2 + sense in that any type dominates Unknown. The optional + resolve parameter specifies whether, in the case of a type + variable and a succesful join, to return the resolved join type, + or to return the (first) type variable for readability */ + let rec join = + (~resolve=false, ~fix, ctx: Ctx.t, ty1: t, ty2: t): option(t) => { + let join' = join(~resolve, ~fix, ctx); + switch (ty1, ty2) { + | (_, Unknown(TypeHole | Free(_)) as ty) when fix => + /* NOTE(andrew): This is load bearing + for ensuring that function literals get appropriate + casts. Examples/Dynamics has regression tests */ + Some(ty) + | (Unknown(p1), Unknown(p2)) => + Some(Unknown(join_type_provenance(p1, p2))) + | (Unknown(_), ty) + | (ty, Unknown(_)) => Some(ty) + | (Var(n1), Var(n2)) => + if (n1 == n2) { + Some(Var(n1)); + } else { + let* ty1 = Ctx.lookup_alias(ctx, n1); + let* ty2 = Ctx.lookup_alias(ctx, n2); + let+ ty_join = join'(ty1, ty2); + !resolve && eq(ty1, ty_join) ? Var(n1) : ty_join; + } + | (Var(name), ty) + | (ty, Var(name)) => + let* ty_name = Ctx.lookup_alias(ctx, name); + let+ ty_join = join'(ty_name, ty); + !resolve && eq(ty_name, ty_join) ? Var(name) : ty_join; + /* Note: Ordering of Unknown, Var, and Rec above is load-bearing! */ + | (Rec(x1, ty1), Rec(x2, ty2)) => + /* TODO: + This code isn't fully correct, as we may be doing + substitution on open terms; if x1 occurs in ty2, + we should be substituting x1 for a fresh variable + in ty2. This is annoying, and should be obviated + by the forthcoming debruijn index implementation + */ + let ctx = Ctx.extend_dummy_tvar(ctx, x1); + let+ ty_body = + join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); + Rec(x1, ty_body); + | (Rec(_), _) => None + | (Int, Int) => Some(Int) + | (Int, _) => None + | (Float, Float) => Some(Float) + | (Float, _) => None + | (Bool, Bool) => Some(Bool) + | (Bool, _) => None + | (String, String) => Some(String) + | (String, _) => None + | (Arrow(ty1, ty2), Arrow(ty1', ty2')) => + let* ty1 = join'(ty1, ty1'); + let+ ty2 = join'(ty2, ty2'); + Arrow(ty1, ty2); + | (Arrow(_), _) => None + | (Prod(tys1), Prod(tys2)) => + let* tys = ListUtil.map2_opt(join', tys1, tys2); + let+ tys = OptUtil.sequence(tys); + Prod(tys); + | (Prod(_), _) => None + | (Sum(sm1), Sum(sm2)) => + let (sorted1, sorted2) = + /* If same order, retain order for UI */ + ConstructorMap.same_constructors_same_order(sm1, sm2) + ? (sm1, sm2) + : (ConstructorMap.sort(sm1), ConstructorMap.sort(sm2)); + let* ty = + ListUtil.map2_opt( + join_sum_entries(~resolve, ~fix, ctx), + sorted1, + sorted2, + ); + let+ ty = OptUtil.sequence(ty); + Sum(ty); + | (Sum(_), _) => None + | (List(ty1), List(ty2)) => + let+ ty = join'(ty1, ty2); + List(ty); + | (List(_), _) => None + }; + } + and join_sum_entries = + ( + ~resolve, + ~fix, + ctx: Ctx.t, + (ctr1, ty1): sum_entry, + (ctr2, ty2): sum_entry, + ) + : option(sum_entry) => + switch (ty1, ty2) { + | (None, None) when ctr1 == ctr2 => Some((ctr1, None)) + | (Some(ty1), Some(ty2)) when ctr1 == ctr2 => + let+ ty_join = join(~resolve, ~fix, ctx, ty1, ty2); + (ctr1, Some(ty_join)); + | _ => None + }; + + let join_fix = join(~fix=true); + + let join_all = (ctx: Ctx.t, ts: list(t)): option(t) => + List.fold_left( + (acc, ty) => OptUtil.and_then(join(~fix=false, ctx, ty), acc), + Some(Unknown(Internal)), + ts, + ); + + let rec weak_head_normalize = (ctx: Ctx.t, ty: t): t => + switch (ty) { + | Var(x) => + switch (Ctx.lookup_alias(ctx, x)) { + | Some(ty) => weak_head_normalize(ctx, ty) + | None => ty + } + | _ => ty + }; + + let rec normalize = (ctx: Ctx.t, ty: t): t => { + switch (ty) { + | Var(x) => + switch (Ctx.lookup_alias(ctx, x)) { + | Some(ty) => normalize(ctx, ty) + | None => ty + } + | Unknown(_) + | Int + | Float + | Bool + | String => ty + | List(t) => List(normalize(ctx, t)) + | Arrow(t1, t2) => Arrow(normalize(ctx, t1), normalize(ctx, t2)) + | Prod(ts) => Prod(List.map(normalize(ctx), ts)) + | Sum(ts) => Sum(ConstructorMap.map(Option.map(normalize(ctx)), ts)) + | Rec(name, ty) => + /* NOTE: Dummy tvar added has fake id but shouldn't matter + as in current implementation Recs do not occur in the + surface syntax, so we won't try to jump to them. */ + Rec(name, normalize(Ctx.extend_dummy_tvar(ctx, name), ty)) + }; + }; + + let sum_entry = (ctr: Constructor.t, ctrs: sum_map): option(sum_entry) => + List.find_map( + fun + | (t, typ) when Constructor.equal(t, ctr) => Some((t, typ)) + | _ => None, + ctrs, + ); + + let get_sum_constructors = (ctx: Ctx.t, ty: t): option(sum_map) => { + let ty = weak_head_normalize(ctx, ty); + switch (ty) { + | Sum(sm) => Some(sm) + | Rec(_) => + /* Note: We must unroll here to get right ctr types; + otherwise the rec parameter will leak */ + switch (unroll(ty)) { + | Sum(sm) => Some(sm) + | _ => None + } + | _ => None + }; + }; +} +and Ctx: { + [@deriving (show({with_path: false}), sexp, yojson)] + type var_entry = { + name: Var.t, + id: Id.t, + typ: Typ.t, + }; + + [@deriving (show({with_path: false}), sexp, yojson)] + type tvar_entry = { + name: TypVar.t, + id: Id.t, + kind: Kind.t, + }; + + [@deriving (show({with_path: false}), sexp, yojson)] + type entry = + | VarEntry(var_entry) + | ConstructorEntry(var_entry) + | TVarEntry(tvar_entry); + + [@deriving (show({with_path: false}), sexp, yojson)] + type t = list(entry); + + let extend: (t, entry) => t; + let extend_tvar: (t, tvar_entry) => t; + let extend_alias: (t, TypVar.t, Id.t, Typ.t) => t; + let extend_dummy_tvar: (t, TypVar.t) => t; + let lookup: (t, Var.t) => option(entry); + let lookup_tvar: (t, TypVar.t) => option(tvar_entry); + let lookup_alias: (t, TypVar.t) => option(Typ.t); + let get_id: entry => int; + let lookup_var: (t, string) => option(var_entry); + let lookup_ctr: (t, string) => option(var_entry); + let is_alias: (t, TypVar.t) => bool; + let add_ctrs: (t, TypVar.t, Id.t, Typ.sum_map) => t; + let subtract_prefix: (t, t) => option(t); + let added_bindings: (t, t) => t; + let filter_duplicates: t => t; + let shadows_typ: (t, TypVar.t) => bool; +} = { + [@deriving (show({with_path: false}), sexp, yojson)] + type var_entry = { + name: Var.t, + id: Id.t, + typ: Typ.t, + }; + + [@deriving (show({with_path: false}), sexp, yojson)] + type tvar_entry = { + name: TypVar.t, + id: Id.t, + kind: Kind.t, + }; + + [@deriving (show({with_path: false}), sexp, yojson)] + type entry = + | VarEntry(var_entry) + | ConstructorEntry(var_entry) + | TVarEntry(tvar_entry); + + [@deriving (show({with_path: false}), sexp, yojson)] + type t = list(entry); + + let extend = (ctx, entry) => List.cons(entry, ctx); + + let lookup = (ctx: t, name) => + List.find_map( + fun + | VarEntry(v) when v.name == name => Some(VarEntry(v)) + | ConstructorEntry(v) when v.name == name => Some(ConstructorEntry(v)) + | TVarEntry(v) when v.name == name => Some(TVarEntry(v)) + | _ => None, + ctx, + ); + + let extend_tvar = (ctx: t, tvar_entry: tvar_entry): t => + extend(ctx, TVarEntry(tvar_entry)); + + let extend_alias = (ctx: t, name: TypVar.t, id: Id.t, ty: Typ.t): t => + extend_tvar(ctx, {name, id, kind: Singleton(ty)}); + + let extend_dummy_tvar = (ctx: t, name: TypVar.t) => + extend_tvar(ctx, {kind: Abstract, name, id: Id.invalid}); + + let lookup_tvar = (ctx: t, name: TypVar.t): option(tvar_entry) => + List.find_map( + fun + | TVarEntry(v) when v.name == name => Some(v) + | _ => None, + ctx, + ); + + let lookup_alias = (ctx: t, t: TypVar.t): option(Typ.t) => + switch (lookup_tvar(ctx, t)) { + | Some({kind: Singleton(ty), _}) => Some(ty) + | Some({kind: Abstract, _}) + | _ => None + }; + + let get_id: entry => int = + fun + | VarEntry({id, _}) + | ConstructorEntry({id, _}) + | TVarEntry({id, _}) => id; + + let lookup_var = (ctx: t, name: string): option(var_entry) => + switch (lookup(ctx, name)) { + | Some(VarEntry(v)) => Some(v) + | _ => None + }; + + let lookup_ctr = (ctx: t, name: string): option(var_entry) => + switch (lookup(ctx, name)) { + | Some(ConstructorEntry(t)) => Some(t) + | _ => None + }; + + let is_alias = (ctx: t, name: TypVar.t): bool => + switch (lookup_alias(ctx, name)) { + | Some(_) => true + | None => false + }; + + let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => + List.map( + ((ctr, typ)) => + ConstructorEntry({ + name: ctr, + id, + typ: + switch (typ) { + | None => Var(name) + | Some(typ) => Arrow(typ, Var(name)) + }, + }), + ctrs, + ) + @ ctx; + + let subtract_prefix = (ctx: t, prefix_ctx: t): option(t) => { + // NOTE: does not check that the prefix is an actual prefix + let prefix_length = List.length(prefix_ctx); + let ctx_length = List.length(ctx); + if (prefix_length > ctx_length) { + None; + } else { + Some( + List.rev( + ListUtil.sublist((prefix_length, ctx_length), List.rev(ctx)), + ), + ); + }; + }; + + let added_bindings = (ctx_after: t, ctx_before: t): t => { + /* Precondition: new_ctx is old_ctx plus some new bindings */ + let new_count = List.length(ctx_after) - List.length(ctx_before); + switch (ListUtil.split_n_opt(new_count, ctx_after)) { + | Some((ctx, _)) => ctx + | _ => [] + }; + }; + + module VarSet = Set.Make(Var); + + // Note: filter out duplicates when rendering + let filter_duplicates = (ctx: t): t => + ctx + |> List.fold_left( + ((ctx, term_set, typ_set), entry) => { + switch (entry) { + | VarEntry({name, _}) + | ConstructorEntry({name, _}) => + VarSet.mem(name, term_set) + ? (ctx, term_set, typ_set) + : ([entry, ...ctx], VarSet.add(name, term_set), typ_set) + | TVarEntry({name, _}) => + VarSet.mem(name, typ_set) + ? (ctx, term_set, typ_set) + : ([entry, ...ctx], term_set, VarSet.add(name, typ_set)) + } + }, + ([], VarSet.empty, VarSet.empty), + ) + |> (((ctx, _, _)) => List.rev(ctx)); + + let shadows_typ = (ctx: t, name: TypVar.t): bool => + Form.is_base_typ(name) || lookup_alias(ctx, name) != None; +} +and Kind: { + [@deriving (show({with_path: false}), sexp, yojson)] + type t = + | Singleton(Typ.t) + | Abstract; +} = { + [@deriving (show({with_path: false}), sexp, yojson)] + type t = + | Singleton(Typ.t) + | Abstract; +}; diff --git a/src/haz3lcore/statics/TypVar.re b/src/haz3lcore/statics/TypVar.re new file mode 100644 index 0000000000..7b4f4d4ef2 --- /dev/null +++ b/src/haz3lcore/statics/TypVar.re @@ -0,0 +1,6 @@ +open Sexplib.Std; + +[@deriving (show({with_path: false}), sexp, yojson)] +type t = string; + +let eq = String.equal; diff --git a/src/haz3lcore/dynamics/Var.re b/src/haz3lcore/statics/Var.re similarity index 100% rename from src/haz3lcore/dynamics/Var.re rename to src/haz3lcore/statics/Var.re diff --git a/src/haz3lcore/tiles/Id.re b/src/haz3lcore/tiles/Id.re index ca1ec111e4..8b578284ea 100644 --- a/src/haz3lcore/tiles/Id.re +++ b/src/haz3lcore/tiles/Id.re @@ -1,5 +1,72 @@ open Sexplib.Std; +/* ID FAQ + + WHAT ARE IDS USED FOR? + + Unique ids are assigned to tiles (and hence, indirectly, to terms) + at the time of creation of surface syntax. Ids are used as keys in + various maps (mostly notably the Measured map, which tracks screen + coordinates for the view, and the Info map which collects static + data such as type information). + + BUT WHY IS THERE A _LIST_ OF IDS? + + Technically, each tile has a list of ids, to support n-ary forms like + tuples; there are rep_id functions in Term to canonically extract + single representative ids from this list where appropriate. + + HOW ARE NEW IDS CREATED? + + In the parts of the implementation which manipulate Zippers, fresh id + creation is done by threading an IdGen parameter through all of the + (functions which call) functions where new tiles can be created. This + generally follows the state monad pattern. When a fresh Id is required, + the current value of the IdGen is used, and the IdGen is incremented + and must then be returned to the caller. + + The threading of IdGen through essentially all syntax modification + functions presents a significant complication for the action code, + and may eventually be replaced it with a mutable ref. + + WHERE DOES IDGEN LIVE? + + The initial IdGen passed to zipper functions is generally packaged + along with a zipper through the Zipper.state type. Although in + principle the initial IdGen could be set by traversing the zipper + and finding the largest Id, to avoid this traversal we track the + IdGen along with the zipper state. Each editor mode is responsible + for this tracking. Ultimately, each zipper action which can result in + new Ids being created must be sandwiched by calls to + Editors.get_editor_and_id and Editors.put_editor_and_id, to ensure that + IdGen state is tracked between actions and properly serialized to + local storage. + + HOW DO I GENERATE FRESH IDS FOR MY USE CASE? + + Currently there is no easy way to generate fresh IDs in places one + might concievably want them after Term creation, for example in the + elaborator or evaluator. Doing so is a significant change with + indirect implications for architrcture and performance; ask Andrew + about your use case before attempting this. For some uses, a dummy id + may be sufficient; this should be documented and use Id.invalid or + another similar label rather than magic literals. If you do need to + generated genuinely fresh IDs, then you'll need (A) a strategy + to route an IdGen to/from your use site to the aformentioned + Editors functions, and a traversal/mutation strategy within your + context of use. + + IDS IN DYNAMICS: + + Currently, DHExps (as produced by the elaborator and produced/consumed + by the evaluator) do not in general persist ids; the exceptions are + things like holes and tests which have additional metadata which is + accumulated duting evaluation. There are many use cases for tracking + ids more generally during evaluation, but doing so in a principled + way is a large-scale change with architectural implications. + + */ + [@deriving (show({with_path: false}), sexp, yojson)] type t = int; let compare = Int.compare; diff --git a/src/haz3lcore/tiles/Segment.re b/src/haz3lcore/tiles/Segment.re index 2d487f3fb9..9f107989cc 100644 --- a/src/haz3lcore/tiles/Segment.re +++ b/src/haz3lcore/tiles/Segment.re @@ -121,6 +121,7 @@ let rec remold = (~shape=Nib.Shape.concave(), seg: t, s: Sort.t) => | Pat => remold_pat(shape, seg) | Exp => remold_exp(shape, seg) | Rul => remold_rul(shape, seg) + | TPat => remold_tpat(shape, seg) | _ => failwith("remold unexpected") } and remold_tile = (s: Sort.t, shape, t: Tile.t): option(Tile.t) => { @@ -251,6 +252,26 @@ and remold_pat = (shape, seg: t): t => } } } +and remold_tpat = (shape, seg: t): t => + switch (seg) { + | [] => [] + | [hd, ...tl] => + switch (hd) { + | Secondary(_) + | Grout(_) => [hd, ...remold_tpat(shape, tl)] + | Tile(t) => + switch (remold_tile(TPat, shape, t)) { + | None => [Tile(t), ...remold_tpat(snd(Tile.shapes(t)), tl)] + | Some(t) => + switch (Tile.nibs(t)) { + | (_, {shape, sort: Typ}) => + let (remolded, shape, rest) = remold_typ_uni(shape, tl); + [Piece.Tile(t), ...remolded] @ remold_tpat(shape, rest); + | _ => [Tile(t), ...remold_tpat(snd(Tile.shapes(t)), tl)] + } + } + } + } and remold_exp_uni = (shape, seg: t): (t, Nib.Shape.t, t) => switch (seg) { | [] => ([], shape, []) diff --git a/src/haz3lcore/tiles/Skel.re b/src/haz3lcore/tiles/Skel.re index 0fd2a4e6f5..8d11c40961 100644 --- a/src/haz3lcore/tiles/Skel.re +++ b/src/haz3lcore/tiles/Skel.re @@ -88,6 +88,7 @@ let rel = (p1: Piece.t, p2: Piece.t): option(rel) => lbl1(case) && lbl2(rule), lbl1(rule) && lbl2(rule), lbl1(comma) && lbl2(comma) && t1.mold == t2.mold, + lbl1(["+"]) && lbl2(["+"]) && t1.mold == t2.mold, ] |> List.fold_left((||), false); if (eq) { @@ -170,7 +171,11 @@ module Stacks = { | (_, Some((l, r))) => let is = List.map(fst, chain); let split_kids = n => - ListUtil.split_n(n, stacks.output) |> PairUtil.map_fst(List.rev); + try(ListUtil.split_n(n, stacks.output) |> PairUtil.map_fst(List.rev)) { + | _ => + print_endline(show(stacks)); + failwith("Skel.push_output: split_kids: index out of bounds"); + }; let output = switch (l, r) { | (Convex, Convex) => diff --git a/src/haz3lcore/zipper/Editor.re b/src/haz3lcore/zipper/Editor.re index 70d7f76542..6ac16b3cda 100644 --- a/src/haz3lcore/zipper/Editor.re +++ b/src/haz3lcore/zipper/Editor.re @@ -156,7 +156,7 @@ let can_redo = ed => Option.is_some(redo(ed)); let set_read_only = (ed, read_only) => {...ed, read_only}; -let trailing_hole_ctx = (ed: t, info_map: Statics.map) => { +let trailing_hole_ctx = (ed: t, info_map: Statics.Map.t) => { let segment = Zipper.unselect_and_zip(ed.state.zipper); let convex_grout = Segment.convex_grout(segment); // print_endline(String.concat("; ", List.map(Grout.show, convex_grout))); @@ -167,7 +167,7 @@ let trailing_hole_ctx = (ed: t, info_map: Statics.map) => { let id = grout.id; let info = Id.Map.find_opt(id, info_map); switch (info) { - | Some(InfoExp(info_exp)) => Some(info_exp.ctx) + | Some(info) => Some(Info.ctx_of(info)) | _ => None }; }; diff --git a/src/haz3lcore/zipper/EditorUtil.re b/src/haz3lcore/zipper/EditorUtil.re index 02e0652d70..c504144bcd 100644 --- a/src/haz3lcore/zipper/EditorUtil.re +++ b/src/haz3lcore/zipper/EditorUtil.re @@ -64,7 +64,7 @@ let rec append_exp = (id, e1: TermBase.UExp.t, e2: TermBase.UExp.t) => { | Float(_) | String(_) | ListLit(_) - | Tag(_) + | Constructor(_) | Fun(_) | Tuple(_) | Var(_) @@ -88,6 +88,9 @@ let rec append_exp = (id, e1: TermBase.UExp.t, e2: TermBase.UExp.t) => { | Let(p, edef, ebody) => let (id, ebody') = append_exp(id, ebody, e2); (id, TermBase.UExp.{ids: e1.ids, term: Let(p, edef, ebody')}); + | TyAlias(tp, tdef, ebody) => + let (id, ebody') = append_exp(id, ebody, e2); + (id, TermBase.UExp.{ids: e1.ids, term: TyAlias(tp, tdef, ebody')}); }; }; diff --git a/src/haz3lcore/zipper/action/Perform.re b/src/haz3lcore/zipper/action/Perform.re index fc2fec547b..7165081045 100644 --- a/src/haz3lcore/zipper/action/Perform.re +++ b/src/haz3lcore/zipper/action/Perform.re @@ -50,8 +50,9 @@ let go_z = ( switch (jump_target) { | BindingSiteOfIndicatedVar => - let* binding_id = - Option.bind(idx, Statics.get_binding_site(_, statics)); + let* idx = idx; + let* ci = Id.Map.find_opt(idx, statics); + let* binding_id = Info.get_binding_site(ci); Move.jump_to_id(z, binding_id); | TileId(id) => Move.jump_to_id(z, id) } diff --git a/src/haz3lschool/SchoolExercise.re b/src/haz3lschool/Exercise.re similarity index 98% rename from src/haz3lschool/SchoolExercise.re rename to src/haz3lschool/Exercise.re index 8b74b3dc51..057a2c171f 100644 --- a/src/haz3lschool/SchoolExercise.re +++ b/src/haz3lschool/Exercise.re @@ -8,8 +8,7 @@ module type ExerciseEnv = { }; let output_header_grading = _module_name => - "module SchoolExercise = GradePrelude.SchoolExercise\n" - ++ "let prompt = ()\n"; + "module Exercise = GradePrelude.Exercise\n" ++ "let prompt = ()\n"; module F = (ExerciseEnv: ExerciseEnv) => { [@deriving (show({with_path: false}), sexp, yojson)] @@ -572,7 +571,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { module StaticsItem = { type t = { term: TermBase.UExp.t, - info_map: Statics.map, + info_map: Statics.Map.t, }; }; @@ -725,7 +724,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { module DynamicsItem = { type t = { term: TermBase.UExp.t, - info_map: Statics.map, + info_map: Statics.Map.t, simple_result: ModelResult.simple, }; }; @@ -857,7 +856,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { "let prompt = " ++ module_name ++ "_prompt.prompt\n" - ++ "let exercise: SchoolExercise.spec = "; + ++ "let exercise: Exercise.spec = "; let record = show_p(editor_pp, eds); let data = prefix ++ record ++ "\n"; data; @@ -874,7 +873,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { "let prompt = " ++ module_name ++ "_prompt.prompt\n" - ++ "let exercise: SchoolExercise.spec = SchoolExercise.transition("; + ++ "let exercise: Exercise.spec = Exercise.transition("; let record = show_p(transitionary_editor_pp, eds); let data = prefix ++ record ++ ")\n"; data; @@ -882,7 +881,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { let export_grading_module = (module_name, {eds, _}: state) => { let header = output_header_grading(module_name); - let prefix = "let exercise: SchoolExercise.spec = "; + let prefix = "let exercise: Exercise.spec = "; let record = show_p(editor_pp, eds); let data = header ++ prefix ++ record ++ "\n"; data; @@ -935,10 +934,10 @@ module F = (ExerciseEnv: ExerciseEnv) => { }; }; - // From LocalStorage + // From Store [@deriving (show({with_path: false}), sexp, yojson)] - type school_export = { + type exercise_export = { cur_exercise: key, exercise_data: list((key, persistent_state)), }; @@ -956,7 +955,7 @@ module F = (ExerciseEnv: ExerciseEnv) => { |> unpersist_state(~spec, ~instructor_mode); }; - let deserialize_school_export = data => { - data |> Sexplib.Sexp.of_string |> school_export_of_sexp; + let deserialize_exercise_export = data => { + data |> Sexplib.Sexp.of_string |> exercise_export_of_sexp; }; }; diff --git a/src/haz3lschool/GradePrelude.re b/src/haz3lschool/GradePrelude.re index 4a84398706..a45b34fa15 100644 --- a/src/haz3lschool/GradePrelude.re +++ b/src/haz3lschool/GradePrelude.re @@ -1,9 +1,9 @@ module ExerciseEnv = { type node = unit; let default = (); - let output_header = SchoolExercise.output_header_grading; + let output_header = Exercise.output_header_grading; }; -module SchoolExercise = SchoolExercise.F(ExerciseEnv); +module Exercise = Exercise.F(ExerciseEnv); module Grading = Grading.F(ExerciseEnv); diff --git a/src/haz3lschool/Gradescope.re b/src/haz3lschool/Gradescope.re index 1c43ef3288..3c4e2d3314 100644 --- a/src/haz3lschool/Gradescope.re +++ b/src/haz3lschool/Gradescope.re @@ -4,7 +4,7 @@ open Haz3lschool; open Core; open Specs; -open GradePrelude.SchoolExercise; +open GradePrelude.Exercise; open GradePrelude.Grading; [@deriving (sexp, yojson)] @@ -44,15 +44,15 @@ type section = { type chapter = list(section); module Main = { - let name_to_school_export = path => { + let name_to_exercise_export = path => { let yj = Yojson.Safe.from_file(path); switch (yj) { | `Assoc(l) => let sch = List.Assoc.find_exn(~equal=String.(==), l, "school"); switch (sch) { | `String(sch) => - let school_export = sch |> deserialize_school_export; - school_export; + let exercise_export = sch |> deserialize_exercise_export; + exercise_export; | _ => failwith("School is not a string") }; | _ => failwith("Json without school key") @@ -98,7 +98,7 @@ module Main = { }; let run = () => { let hw_path = Sys.get_argv()[1]; - let hw = name_to_school_export(hw_path); + let hw = name_to_exercise_export(hw_path); let export_chapter = hw.exercise_data |> List.map(~f=(((name, _) as key, persistent_state)) => { diff --git a/src/haz3lschool/Grading.re b/src/haz3lschool/Grading.re index 948afd49b2..d20a490610 100644 --- a/src/haz3lschool/Grading.re +++ b/src/haz3lschool/Grading.re @@ -1,8 +1,8 @@ open Haz3lcore; open Sexplib.Std; -module F = (ExerciseEnv: SchoolExercise.ExerciseEnv) => { - open SchoolExercise.F(ExerciseEnv); +module F = (ExerciseEnv: Exercise.ExerciseEnv) => { + open Exercise.F(ExerciseEnv); [@deriving (show({with_path: false}), sexp, yojson)] type percentage = float; diff --git a/src/haz3lweb/DebugAction.re b/src/haz3lweb/DebugAction.re index 6258163f5c..f25af2897c 100644 --- a/src/haz3lweb/DebugAction.re +++ b/src/haz3lweb/DebugAction.re @@ -1,13 +1,13 @@ [@deriving (show({with_path: false}), sexp, yojson)] type t = | TurnOffDynamics - | ClearLocalStorage; + | ClearStore; let perform = action => { switch (action) { | TurnOffDynamics => - let settings = LocalStorage.Settings.load(); - LocalStorage.Settings.save({...settings, dynamics: false}); - | ClearLocalStorage => JsUtil.clear_localstore() + let settings = Store.Settings.load(); + Store.Settings.save({...settings, dynamics: false}); + | ClearStore => JsUtil.clear_localstore() }; }; diff --git a/src/haz3lweb/Editors.re b/src/haz3lweb/Editors.re index eafd68a308..85a700ed86 100644 --- a/src/haz3lweb/Editors.re +++ b/src/haz3lweb/Editors.re @@ -2,29 +2,20 @@ open Sexplib.Std; open Haz3lcore; [@deriving (show({with_path: false}), sexp, yojson)] -type t = - | DebugLoad - | Scratch(int, list(ScratchSlide.state)) - | School(int, list(SchoolExercise.spec), SchoolExercise.state); +type scratch = (int, list(ScratchSlide.state)); [@deriving (show({with_path: false}), sexp, yojson)] -type scratch = (int, list(ScratchSlide.state)); +type examples = (string, list((string, ScratchSlide.state))); [@deriving (show({with_path: false}), sexp, yojson)] -type school = (int, list(SchoolExercise.spec), SchoolExercise.state); +type exercises = (int, list(Exercise.spec), Exercise.state); [@deriving (show({with_path: false}), sexp, yojson)] -type mode = +type t = | DebugLoad - | Scratch - | School; - -let rotate_mode = (editors: t) => - switch (editors) { - | DebugLoad => DebugLoad - | Scratch(_) => School - | School(_) => Scratch - }; + | Scratch(int, list(ScratchSlide.state)) + | Examples(string, list((string, ScratchSlide.state))) + | Exercise(int, list(Exercise.spec), Exercise.state); let get_editor_and_id = (editors: t): (Id.t, Editor.t) => switch (editors) { @@ -35,9 +26,15 @@ let get_editor_and_id = (editors: t): (Id.t, Editor.t) => let id = ScratchSlide.id_of_state(slide); let ed = ScratchSlide.editor_of_state(slide); (id, ed); - | School(_, _, exercise) => - let id = SchoolExercise.id_of_state(exercise); - let ed = SchoolExercise.editor_of_state(exercise); + | Examples(name, slides) => + assert(List.mem_assoc(name, slides)); + let slide = List.assoc(name, slides); + let id = ScratchSlide.id_of_state(slide); + let ed = ScratchSlide.editor_of_state(slide); + (id, ed); + | Exercise(_, _, exercise) => + let id = Exercise.id_of_state(exercise); + let ed = Exercise.editor_of_state(exercise); (id, ed); }; @@ -57,8 +54,17 @@ let put_editor_and_id = (id: Id.t, ed: Editor.t, eds: t): t => slides, ), ); - | School(n, specs, exercise) => - School(n, specs, SchoolExercise.put_editor_and_id(exercise, id, ed)) + | Examples(name, slides) => + assert(List.mem_assoc(name, slides)); + let slide = List.assoc(name, slides); + Examples( + name, + slides + |> List.remove_assoc(name) + |> List.cons((name, ScratchSlide.put_editor_and_id(slide, id, ed))), + ); + | Exercise(n, specs, exercise) => + Exercise(n, specs, Exercise.put_editor_and_id(exercise, id, ed)) }; let get_zipper = (editors: t): Zipper.t => get_editor(editors).state.zipper; @@ -69,32 +75,73 @@ let get_spliced_elabs = (editors: t): list((ModelResults.key, DHExp.t)) => { | Scratch(n, slides) => let slide = List.nth(slides, n); ScratchSlide.spliced_elabs(slide); - | School(_, _, exercise) => SchoolExercise.spliced_elabs(exercise) + | Examples(name, slides) => + let slide = List.assoc(name, slides); + ScratchSlide.spliced_elabs(slide); + | Exercise(_, _, exercise) => Exercise.spliced_elabs(exercise) }; }; let set_instructor_mode = (editors: t, instructor_mode: bool): t => switch (editors) { | DebugLoad => failwith("no editors in debug load mode") - | Scratch(_) => editors - | School(n, specs, exercise) => - School( + | Scratch(_) + | Examples(_) => editors + | Exercise(n, specs, exercise) => + Exercise( n, specs, - SchoolExercise.set_instructor_mode(exercise, instructor_mode), + Exercise.set_instructor_mode(exercise, instructor_mode), ) }; -let num_slides = (editors: t): int => +let reset_nth_slide = (n, slides) => { + let data = List.nth(Init.startup.scratch |> snd, n); + let init_nth = ScratchSlide.unpersist(data); + Util.ListUtil.put_nth(n, init_nth, slides); +}; + +let reset_named_slide = (name, slides) => { + let data = List.assoc(name, Init.startup.examples |> snd); + let init_name = ScratchSlide.unpersist(data); + slides |> List.remove_assoc(name) |> List.cons((name, init_name)); +}; + +let reset_current = (editors: t, ~instructor_mode: bool): t => switch (editors) { - | DebugLoad => 0 - | Scratch(_, slides) => List.length(slides) - | School(_, specs, _) => List.length(specs) + | DebugLoad => failwith("impossible") + | Scratch(n, slides) => Scratch(n, reset_nth_slide(n, slides)) + | Examples(name, slides) => + Examples(name, reset_named_slide(name, slides)) + | Exercise(n, specs, _) => + Exercise( + n, + specs, + List.nth(specs, n) |> Exercise.state_of_spec(~instructor_mode), + ) + }; + +let import_current = (editors: t, data: option(string)): t => + switch (editors) { + | DebugLoad + | Examples(_) + | Exercise(_) => failwith("impossible") + | Scratch(idx, slides) => + switch (data) { + | None => editors + | Some(data) => + let state = ScratchSlide.import(data); + let slides = Util.ListUtil.put_nth(idx, state, slides); + Scratch(idx, slides); + } }; -let cur_slide = (editors: t): int => +let switch_example_slide = (editors: t, name: string): option(t) => switch (editors) { - | DebugLoad => 0 - | Scratch(n, _) - | School(n, _, _) => n + | DebugLoad + | Scratch(_) + | Exercise(_) => None + | Examples(cur, slides) when !List.mem_assoc(name, slides) || cur == name => + None + | Examples(_, slides) => Some(Examples(name, slides)) }; diff --git a/src/haz3lweb/SchoolExercise.re b/src/haz3lweb/Exercise.re similarity index 80% rename from src/haz3lweb/SchoolExercise.re rename to src/haz3lweb/Exercise.re index c209dff2f2..ec187c90db 100644 --- a/src/haz3lweb/SchoolExercise.re +++ b/src/haz3lweb/Exercise.re @@ -7,4 +7,4 @@ module ExerciseEnv = { "let prompt = " ++ module_name ++ "_prompt.prompt\n"; }; -include Haz3lschool.SchoolExercise.F(ExerciseEnv); +include Haz3lschool.Exercise.F(ExerciseEnv); diff --git a/src/haz3lweb/ExerciseSettings.re b/src/haz3lweb/ExerciseSettings.re new file mode 100644 index 0000000000..09f0735d77 --- /dev/null +++ b/src/haz3lweb/ExerciseSettings.re @@ -0,0 +1,2 @@ +include ExerciseSettings_base; +let show_instructor = true; diff --git a/src/haz3lweb/SchoolSettings_base.re b/src/haz3lweb/ExerciseSettings_base.re similarity index 72% rename from src/haz3lweb/SchoolSettings_base.re rename to src/haz3lweb/ExerciseSettings_base.re index b39716cfe5..c97171c755 100644 --- a/src/haz3lweb/SchoolSettings_base.re +++ b/src/haz3lweb/ExerciseSettings_base.re @@ -1,6 +1,6 @@ let filename = "haz3l-demo"; let log_key = filename; -let exercises: list(SchoolExercise.spec) = [ +let exercises: list(Exercise.spec) = [ Ex_OddlyRecursive.exercise, Ex_RecursiveFibonacci.exercise, ]; diff --git a/src/haz3lweb/ExerciseSettings_instructor.re b/src/haz3lweb/ExerciseSettings_instructor.re new file mode 100644 index 0000000000..09f0735d77 --- /dev/null +++ b/src/haz3lweb/ExerciseSettings_instructor.re @@ -0,0 +1,2 @@ +include ExerciseSettings_base; +let show_instructor = true; diff --git a/src/haz3lweb/ExerciseSettings_student.re b/src/haz3lweb/ExerciseSettings_student.re new file mode 100644 index 0000000000..e18079d14c --- /dev/null +++ b/src/haz3lweb/ExerciseSettings_student.re @@ -0,0 +1,2 @@ +include ExerciseSettings_base; +let show_instructor = false; diff --git a/src/haz3lweb/Export.re b/src/haz3lweb/Export.re index 19a4fda72c..ab734aaccf 100644 --- a/src/haz3lweb/Export.re +++ b/src/haz3lweb/Export.re @@ -5,7 +5,8 @@ type all = { settings: string, langDocMessages: string, scratch: string, - school: string, + exercise: string, + examples: string, log: string, }; @@ -14,23 +15,28 @@ type all = { type all_f22 = { settings: string, scratch: string, - school: string, + exercise: string, log: string, }; let mk_all = (~instructor_mode) => { print_endline("Mk all"); - let settings = LocalStorage.Settings.export(); + let settings = Store.Settings.export(); print_endline("Settings OK"); - let langDocMessages = LocalStorage.LangDocMessages.export(); + let langDocMessages = Store.LangDocMessages.export(); print_endline("LangDocMessages OK"); - let scratch = LocalStorage.Scratch.export(); + let scratch = Store.Scratch.export(); print_endline("Scratch OK"); - let specs = School.exercises; - let school = LocalStorage.School.export(~specs, ~instructor_mode); - print_endline("School OK"); + let examples = Store.Examples.export(); + print_endline("Examples OK"); + let exercise = + Store.Exercise.export( + ~specs=ExerciseSettings.exercises, + ~instructor_mode, + ); + print_endline("Exercise OK"); let log = Log.export(); - {settings, langDocMessages, scratch, school, log}; + {settings, langDocMessages, scratch, examples, exercise, log}; }; let export_all = (~instructor_mode) => { @@ -45,15 +51,16 @@ let import_all = (data, ~specs) => { { settings: all_f22.settings, scratch: all_f22.scratch, - school: all_f22.school, + examples: "", + exercise: all_f22.exercise, log: all_f22.log, langDocMessages: "", }; }; - let settings = LocalStorage.Settings.import(all.settings); - LocalStorage.LangDocMessages.import(all.langDocMessages); + let settings = Store.Settings.import(all.settings); + Store.LangDocMessages.import(all.langDocMessages); let instructor_mode = settings.instructor_mode; - LocalStorage.Scratch.import(all.scratch); - LocalStorage.School.import(all.school, ~specs, ~instructor_mode); + Store.Scratch.import(all.scratch); + Store.Exercise.import(all.exercise, ~specs, ~instructor_mode); Log.import(all.log); }; diff --git a/src/haz3lweb/Grading.re b/src/haz3lweb/Grading.re index b3474eb18c..6b3c5568d8 100644 --- a/src/haz3lweb/Grading.re +++ b/src/haz3lweb/Grading.re @@ -1,7 +1,7 @@ open Virtual_dom.Vdom; open Node; -include Haz3lschool.Grading.F(SchoolExercise.ExerciseEnv); +include Haz3lschool.Grading.F(Exercise.ExerciseEnv); let score_view = ((earned: points, max: points)) => { div( diff --git a/src/haz3lweb/Init.ml b/src/haz3lweb/Init.ml new file mode 100644 index 0000000000..fb818acba9 --- /dev/null +++ b/src/haz3lweb/Init.ml @@ -0,0 +1,7336 @@ +let startup : PersistentData.t = + { + settings = + { + captions = true; + secondary_icons = false; + statics = true; + dynamics = true; + async_evaluation = false; + context_inspector = false; + instructor_mode = true; + benchmark = false; + mode = Examples; + }; + scratch = + ( 0, + [ + ( 1416, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(()((Grout((id \ + 1415)(shape Convex))))))(ancestors())))(caret Outer))"; + backup_text = " "; + } ); + ( 281, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Tile((id \ + 236)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 239)(shape \ + Concave)))(Tile((id 244)(label(Option))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 245)(content(Whitespace\" \"))))(Tile((id \ + 246)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 248)(content(Whitespace\" \"))))(Tile((id \ + 252)(label(None))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 253)(content(Whitespace\" \"))))(Tile((id \ + 254)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 256)(content(Whitespace\" \"))))(Tile((id \ + 260)(label(Some))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 261)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 265)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id 268)(shape \ + Concave)))(Tile((id 269)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 270)(content(Whitespace\" \"))))(Secondary((id \ + 271)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 274)(shape Concave)))(Tile((id 277)(label(Some))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 278)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 280)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))()))(ancestors())))(caret \ + Outer))"; + backup_text = "type Option = None + Some(Int) in \n Some(3)"; + } ); + ( 18901, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 16278)(content(Comment\"#Non-recursive sum/alias \ + tests#\"))))(Secondary((id \ + 16279)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16335)(content(Comment\"#all lines with trailing err comment \ + should have 1 error#\"))))(Secondary((id \ + 16336)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16370)(content(Comment\"#no other lines should have \ + errors#\"))))(Secondary((id \ + 16371)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16372)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16400)(content(Comment\"#type definitions: no \ + errors#\"))))(Secondary((id \ + 16401)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 16405)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16406)(content(Whitespace\" \"))))(Secondary((id \ + 16407)(content(Whitespace\" \"))))(Secondary((id \ + 16408)(content(Whitespace\" \"))))(Secondary((id \ + 16409)(content(Whitespace\" \"))))(Tile((id \ + 16410)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16412)(content(Whitespace\" \"))))(Secondary((id \ + 16413)(content(Whitespace\" \"))))(Secondary((id \ + 16414)(content(Whitespace\" \"))))(Secondary((id \ + 16415)(content(Whitespace\" \"))))(Tile((id \ + 16417)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16418)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16421)(shape Concave)))(Tile((id \ + 16424)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16427)(shape \ + Concave)))(Tile((id 16436)(label(SingleNull))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16437)(content(Whitespace\" \"))))(Tile((id \ + 16438)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16440)(content(Whitespace\" \"))))(Secondary((id \ + 16441)(content(Whitespace\" \"))))(Grout((id 16443)(shape \ + Convex)))(Tile((id 16442)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16446)(label(One))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16449)(shape \ + Concave)))(Tile((id 16450)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16451)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16454)(shape Concave)))(Tile((id \ + 16457)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16460)(shape \ + Concave)))(Tile((id 16465)(label(Single))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16466)(content(Whitespace\" \"))))(Tile((id \ + 16467)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16469)(content(Whitespace\" \"))))(Secondary((id \ + 16470)(content(Whitespace\" \"))))(Grout((id 16472)(shape \ + Convex)))(Tile((id 16471)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16473)(label(F))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16474)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 16478)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 16481)(shape Concave)))(Tile((id 16482)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16483)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16486)(shape Concave)))(Tile((id \ + 16489)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16492)(shape \ + Concave)))(Tile((id 16498)(label(GoodSum))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16499)(content(Whitespace\" \"))))(Tile((id \ + 16500)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16502)(content(Whitespace\" \"))))(Tile((id \ + 16503)(label(A))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16504)(content(Whitespace\" \"))))(Tile((id \ + 16505)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16507)(content(Whitespace\" \"))))(Tile((id \ + 16508)(label(B))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16509)(content(Whitespace\" \"))))(Tile((id \ + 16510)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16512)(content(Whitespace\" \"))))(Tile((id \ + 16513)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16514)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 16518)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 16521)(shape Concave)))(Tile((id 16522)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16523)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16526)(shape Concave)))(Tile((id \ + 16529)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16532)(shape \ + Concave)))(Tile((id 16538)(label(Partial))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16539)(content(Whitespace\" \"))))(Tile((id \ + 16540)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16542)(content(Whitespace\" \"))))(Tile((id \ + 16544)(label(Ok))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16545)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Grout((id \ + 16550)(shape Convex)))(Secondary((id \ + 16547)(content(Whitespace\" \"))))(Secondary((id \ + 16548)(content(Whitespace\" \"))))(Secondary((id \ + 16549)(content(Whitespace\" \")))))))))(Secondary((id \ + 16551)(content(Whitespace\" \"))))(Tile((id \ + 16552)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16554)(content(Whitespace\" \"))))(Secondary((id \ + 16555)(content(Whitespace\" \"))))(Secondary((id \ + 16556)(content(Whitespace\" \"))))(Secondary((id \ + 16557)(content(Whitespace\" \"))))(Tile((id \ + 16559)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16560)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16563)(shape Concave)))(Tile((id \ + 16566)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16569)(shape \ + Concave)))(Tile((id 16579)(label(DoubleAlias))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16580)(content(Whitespace\" \"))))(Tile((id \ + 16581)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16583)(content(Whitespace\" \"))))(Tile((id \ + 16590)(label(GoodSum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16593)(shape \ + Concave)))(Tile((id 16594)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16595)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16598)(shape Concave)))(Tile((id \ + 16601)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16604)(shape \ + Concave)))(Tile((id 16618)(label(VerticalLeading))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16619)(content(Whitespace\" \"))))(Tile((id \ + 16620)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16622)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16623)(content(Whitespace\" \"))))(Grout((id 16625)(shape \ + Convex)))(Tile((id 16624)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16626)(content(Whitespace\" \"))))(Tile((id \ + 16627)(label(A))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16628)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 16629)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16631)(content(Whitespace\" \"))))(Tile((id \ + 16632)(label(B))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16633)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 16641)(label(GoodSum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 16642)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 16643)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16645)(content(Whitespace\" \"))))(Tile((id \ + 16646)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16647)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 16652)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16655)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 16659)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 16660)(content(Whitespace\" \"))))(Secondary((id \ + 16661)(content(Whitespace\" \"))))(Secondary((id \ + 16662)(content(Whitespace\" \"))))(Secondary((id \ + 16663)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16665)(shape Concave)))(Tile((id 16666)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16667)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16668)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16709)(content(Comment\"#incorrect or incomplete type \ + definitions#\"))))(Secondary((id \ + 16710)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16713)(shape Concave)))(Tile((id \ + 16716)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16719)(shape \ + Concave)))(Tile((id 16729)(label(badTypeName))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16730)(content(Whitespace\" \"))))(Tile((id \ + 16731)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16733)(content(Whitespace\" \"))))(Secondary((id \ + 16734)(content(Whitespace\" \"))))(Secondary((id \ + 16735)(content(Whitespace\" \"))))(Secondary((id \ + 16736)(content(Whitespace\" \"))))(Tile((id \ + 16738)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16739)(content(Whitespace\" \"))))(Secondary((id \ + 16762)(content(Comment\"#err: invalid type \ + name#\"))))(Secondary((id \ + 16763)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16766)(shape Concave)))(Tile((id \ + 16769)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16770)(content(Whitespace\" \"))))(Tile((id \ + 16771)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Secondary((id \ + 16773)(content(Whitespace\" \"))))(Secondary((id \ + 16774)(content(Whitespace\" \"))))(Secondary((id \ + 16775)(content(Whitespace\" \"))))(Grout((id 16777)(shape \ + Convex)))(Tile((id 16776)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16782)(shape \ + Convex)))(Secondary((id 16778)(content(Whitespace\" \ + \"))))(Secondary((id 16779)(content(Whitespace\" \ + \"))))(Secondary((id 16780)(content(Whitespace\" \ + \"))))(Secondary((id 16781)(content(Whitespace\" \ + \")))))))))(Secondary((id 16783)(content(Whitespace\" \ + \"))))(Tile((id 16784)(label(=))(mold((out \ + Any)(in_())(nibs(((shape(Concave 8))(sort \ + Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16786)(content(Whitespace\" \"))))(Secondary((id \ + 16787)(content(Whitespace\" \"))))(Secondary((id \ + 16788)(content(Whitespace\" \"))))(Secondary((id \ + 16789)(content(Whitespace\" \"))))(Tile((id \ + 16791)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16792)(content(Whitespace\" \"))))(Secondary((id \ + 16815)(content(Comment\"#err: invalid type \ + name#\"))))(Secondary((id \ + 16816)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16819)(shape Concave)))(Tile((id \ + 16822)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16823)(content(Whitespace\" \"))))(Secondary((id \ + 16824)(content(Whitespace\" \"))))(Secondary((id \ + 16825)(content(Whitespace\" \"))))(Secondary((id \ + 16826)(content(Whitespace\" \"))))(Tile((id \ + 16827)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16829)(content(Whitespace\" \"))))(Tile((id \ + 16841)(label(badTypeToken))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Grout((id \ + 16844)(shape Concave)))(Tile((id 16845)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16846)(content(Whitespace\" \"))))(Secondary((id \ + 16870)(content(Comment\"#err: invalid type \ + token#\"))))(Secondary((id \ + 16871)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16874)(shape Concave)))(Tile((id \ + 16877)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16880)(shape \ + Concave)))(Tile((id 16886)(label(NotASum))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16887)(content(Whitespace\" \"))))(Tile((id \ + 16888)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16890)(content(Whitespace\" \"))))(Tile((id \ + 16898)(label(NotInSum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 16899)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 16904)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 16907)(shape Concave)))(Tile((id 16908)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16909)(content(Whitespace\" \"))))(Secondary((id \ + 16930)(content(Comment\"#err: cons not in \ + sum#\"))))(Secondary((id \ + 16931)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16934)(shape Concave)))(Tile((id \ + 16937)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16940)(shape \ + Concave)))(Tile((id 16943)(label(Bool))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16944)(content(Whitespace\" \"))))(Tile((id \ + 16945)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16947)(content(Whitespace\" \"))))(Secondary((id \ + 16948)(content(Whitespace\" \"))))(Secondary((id \ + 16949)(content(Whitespace\" \"))))(Secondary((id \ + 16950)(content(Whitespace\" \"))))(Secondary((id \ + 16951)(content(Whitespace\" \"))))(Tile((id \ + 16953)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16954)(content(Whitespace\" \"))))(Secondary((id \ + 16977)(content(Comment\"#err: shadows base \ + type#\"))))(Secondary((id \ + 16978)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 16981)(shape Concave)))(Tile((id \ + 16984)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 16987)(shape \ + Concave)))(Tile((id 16991)(label(Dupes))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 16992)(content(Whitespace\" \"))))(Tile((id \ + 16993)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 16995)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16996)(content(Whitespace\" \"))))(Grout((id 16998)(shape \ + Convex)))(Tile((id 16997)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 16999)(content(Whitespace\" \"))))(Tile((id \ + 17002)(label(Guy))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17003)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17008)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17009)(content(Whitespace\" \"))))(Secondary((id \ + 17016)(content(Comment\"#no err#\"))))(Secondary((id \ + 17017)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17018)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17020)(content(Whitespace\" \"))))(Tile((id \ + 17023)(label(Guy))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17024)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17028)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17029)(content(Whitespace\" \"))))(Secondary((id \ + 17047)(content(Comment\"#err: already \ + used#\"))))(Secondary((id \ + 17048)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17049)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17051)(content(Whitespace\" \"))))(Tile((id \ + 17054)(label(Guy))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17057)(shape \ + Concave)))(Tile((id 17058)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17059)(content(Whitespace\" \"))))(Secondary((id \ + 17077)(content(Comment\"#err: already \ + used#\"))))(Secondary((id \ + 17078)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17081)(shape Concave)))(Tile((id \ + 17084)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17087)(shape \ + Concave)))(Tile((id 17093)(label(BadCons))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17094)(content(Whitespace\" \"))))(Tile((id \ + 17095)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17097)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17098)(content(Whitespace\" \"))))(Grout((id 17100)(shape \ + Convex)))(Tile((id 17099)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17101)(content(Whitespace\" \"))))(Tile((id \ + 17103)(label(Um))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17104)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17112)(label(Unbound))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17113)(content(Whitespace\" \"))))(Secondary((id \ + 17135)(content(Comment\"#err: unbound type \ + var#\"))))(Secondary((id \ + 17136)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17137)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17139)(content(Whitespace\" \"))))(Secondary((id \ + 17140)(content(Whitespace\" \"))))(Tile((id \ + 17147)(label(invalid))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17148)(content(Whitespace\" \"))))(Secondary((id \ + 17161)(content(Comment\"#err: invalid#\"))))(Secondary((id \ + 17162)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17163)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17165)(content(Whitespace\" \"))))(Tile((id \ + 17169)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17170)(content(Whitespace\" \"))))(Secondary((id \ + 17200)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 17201)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17202)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17204)(content(Whitespace\" \"))))(Tile((id \ + 17207)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17208)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17212)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17213)(content(Whitespace\" \"))))(Secondary((id \ + 17243)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 17244)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17245)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17247)(content(Whitespace\" \"))))(Tile((id \ + 17248)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Grout((id \ + 17252)(shape Convex)))(Secondary((id \ + 17249)(content(Whitespace\" \"))))(Secondary((id \ + 17250)(content(Whitespace\" \"))))(Secondary((id \ + 17251)(content(Whitespace\" \")))))))))(Tile((id \ + 17253)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17257)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17258)(content(Whitespace\" \"))))(Secondary((id \ + 17288)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 17289)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17290)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17292)(content(Whitespace\" \"))))(Tile((id \ + 17293)(label(A))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17294)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17299)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 17300)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17304)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 17307)(shape Concave)))(Tile((id 17308)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17309)(content(Whitespace\" \"))))(Secondary((id \ + 17338)(content(Comment\"#err: expected cons found \ + app#\"))))(Secondary((id \ + 17339)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17340)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17379)(content(Comment\"#nested sum defs dont add tags to \ + scope#\"))))(Secondary((id \ + 17380)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17383)(shape Concave)))(Tile((id \ + 17386)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17389)(shape \ + Concave)))(Tile((id 17399)(label(NestedAlias))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17400)(content(Whitespace\" \"))))(Tile((id \ + 17401)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17403)(content(Whitespace\" \"))))(Tile((id \ + 17404)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17407)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17408)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17410)(content(Whitespace\" \"))))(Tile((id \ + 17419)(label(Anonymous))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17420)(content(Whitespace\" \"))))(Tile((id \ + 17421)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17423)(content(Whitespace\" \"))))(Tile((id \ + 17426)(label(Sum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 17429)(shape Concave)))(Tile((id 17430)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17431)(content(Whitespace\" \"))))(Secondary((id \ + 17432)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17435)(shape Concave)))(Tile((id 17438)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 17439)(content(Whitespace\" \ + \"))))(Tile((id 17441)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 17442)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 17454)(label(NestedAlias))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17455)(content(Whitespace\" \")))))((Secondary((id \ + 17457)(content(Whitespace\" \"))))(Tile((id \ + 17458)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17459)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17460)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17462)(content(Whitespace\" \"))))(Tile((id \ + 17465)(label(Sum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17468)(content(Whitespace\" \")))))))))(Secondary((id \ + 17470)(content(Whitespace\" \"))))(Secondary((id \ + 17487)(content(Comment\"#err: not \ + defined#\"))))(Secondary((id \ + 17488)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17489)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17532)(content(Comment\"#unbound tyvars treated as \ + unknown-typehole#\"))))(Secondary((id \ + 17533)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17537)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 17538)(content(Whitespace\" \"))))(Tile((id \ + 17540)(label(a))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 17541)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 17545)(label(Bad))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17546)(content(Whitespace\" \")))))((Secondary((id \ + 17548)(content(Whitespace\" \"))))(Tile((id \ + 17549)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17552)(content(Whitespace\" \")))))))))(Secondary((id \ + 17554)(content(Whitespace\" \"))))(Tile((id \ + 17555)(label(a))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17556)(content(Whitespace\" \"))))(Tile((id \ + 17559)(label(==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17560)(content(Whitespace\" \"))))(Tile((id \ + 17561)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17562)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17564)(content(Whitespace\" \"))))(Secondary((id \ + 17579)(content(Comment\"#err: not bound#\"))))(Secondary((id \ + 17580)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17581)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17613)(content(Comment\"#non-sum-types cant be \ + recursive#\"))))(Secondary((id \ + 17614)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17618)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17621)(shape \ + Concave)))(Tile((id 17623)(label(Lol))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17624)(content(Whitespace\" \"))))(Tile((id \ + 17625)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17627)(content(Whitespace\" \"))))(Tile((id \ + 17630)(label(Lol))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17633)(shape \ + Concave)))(Tile((id 17634)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17635)(content(Whitespace\" \"))))(Secondary((id \ + 17650)(content(Comment\"#err: not bound#\"))))(Secondary((id \ + 17651)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17652)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17682)(content(Comment\"#no errors: analytic \ + shadowing#\"))))(Secondary((id \ + 17683)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17686)(shape Concave)))(Tile((id \ + 17689)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17692)(shape \ + Concave)))(Tile((id 17696)(label(Tork1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17697)(content(Whitespace\" \"))))(Tile((id \ + 17698)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17700)(content(Whitespace\" \"))))(Secondary((id \ + 17701)(content(Whitespace\" \"))))(Grout((id 17703)(shape \ + Convex)))(Tile((id 17702)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17707)(label(Blob))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17710)(shape \ + Concave)))(Tile((id 17711)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17712)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17715)(shape Concave)))(Tile((id \ + 17718)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17721)(shape \ + Concave)))(Tile((id 17725)(label(Tork2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17726)(content(Whitespace\" \"))))(Tile((id \ + 17727)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17729)(content(Whitespace\" \"))))(Secondary((id \ + 17730)(content(Whitespace\" \"))))(Grout((id 17732)(shape \ + Convex)))(Tile((id 17731)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17736)(label(Blob))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17739)(shape \ + Concave)))(Tile((id 17740)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17741)(content(Whitespace\" \"))))(Secondary((id \ + 17742)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17745)(shape Concave)))(Tile((id 17748)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 17749)(content(Whitespace\" \ + \"))))(Tile((id 17751)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 17752)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 17758)(label(Tork1))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17759)(content(Whitespace\" \")))))((Secondary((id \ + 17761)(content(Whitespace\" \"))))(Tile((id \ + 17765)(label(Blob))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17768)(content(Whitespace\" \")))))))))(Secondary((id \ + 17770)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17771)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 17788)(content(Comment\"#exp tests: \ + happy#\"))))(Secondary((id \ + 17789)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17793)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 17796)(shape \ + Concave)))(Tile((id 17801)(label(YoDawg))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17802)(content(Whitespace\" \"))))(Tile((id \ + 17803)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 17805)(content(Whitespace\" \"))))(Secondary((id \ + 17806)(content(Whitespace\" \"))))(Tile((id \ + 17808)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17809)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17813)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17814)(content(Whitespace\" \"))))(Tile((id \ + 17815)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17817)(content(Whitespace\" \"))))(Tile((id \ + 17819)(label(Bo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17820)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17824)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 17825)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17827)(content(Whitespace\" \"))))(Tile((id \ + 17831)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17832)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17837)(label(Bool))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Grout((id \ + 17840)(shape Concave)))(Tile((id 17841)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 17842)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 17845)(shape Concave)))(Tile((id 17848)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 17849)(content(Whitespace\" \ + \"))))(Tile((id 17851)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 17852)(content(Whitespace\" \")))))((Secondary((id \ + 17854)(content(Whitespace\" \"))))(Tile((id \ + 17856)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17857)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17859)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17862)(content(Whitespace\" \")))))))))(Secondary((id \ + 17864)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17868)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 17869)(content(Whitespace\" \"))))(Tile((id \ + 17871)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 17872)(content(Whitespace\" \"))))(Tile((id \ + 17873)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17875)(content(Whitespace\" \"))))(Tile((id \ + 17881)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17882)(content(Whitespace\" \")))))((Secondary((id \ + 17884)(content(Whitespace\" \"))))(Tile((id \ + 17886)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17887)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17889)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17892)(content(Whitespace\" \")))))))))(Secondary((id \ + 17894)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17898)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 17899)(content(Whitespace\" \"))))(Tile((id \ + 17901)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 17902)(content(Whitespace\" \"))))(Tile((id \ + 17903)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17905)(content(Whitespace\" \"))))(Secondary((id \ + 17906)(content(Whitespace\" \"))))(Grout((id 17908)(shape \ + Convex)))(Tile((id 17907)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17910)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 17911)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 17916)(label(Bool))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 17917)(content(Whitespace\" \")))))((Secondary((id \ + 17919)(content(Whitespace\" \"))))(Tile((id \ + 17921)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17922)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17927)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17930)(content(Whitespace\" \")))))))))(Secondary((id \ + 17932)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17936)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 17937)(content(Whitespace\" \"))))(Tile((id \ + 17939)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 17940)(content(Whitespace\" \"))))(Tile((id \ + 17941)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17943)(content(Whitespace\" \"))))(Tile((id \ + 17944)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 17946)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17947)(content(Whitespace\" \"))))(Tile((id \ + 17948)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 17950)(content(Whitespace\" \"))))(Tile((id \ + 17954)(label(Dawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 17955)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17957)(content(Whitespace\" \"))))(Tile((id \ + 17960)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 17961)(content(Whitespace\" \")))))((Secondary((id \ + 17963)(content(Whitespace\" \"))))(Tile((id \ + 17964)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 17968)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17969)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 17971)(label(5))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 17974)(content(Whitespace\" \")))))))))(Secondary((id \ + 17976)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 17980)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 17981)(content(Whitespace\" \"))))(Tile((id \ + 17983)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 17984)(content(Whitespace\" \"))))(Tile((id \ + 17985)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17987)(content(Whitespace\" \"))))(Tile((id \ + 17998)(label(DoubleAlias))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 17999)(content(Whitespace\" \")))))((Secondary((id \ + 18001)(content(Whitespace\" \"))))(Tile((id \ + 18002)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18003)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18005)(label(4))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18008)(content(Whitespace\" \")))))))))(Secondary((id \ + 18010)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18011)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18029)(content(Comment\"#exp tests: \ + errors#\"))))(Secondary((id \ + 18030)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18034)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18035)(content(Whitespace\" \"))))(Tile((id \ + 18037)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18038)(content(Whitespace\" \")))))((Secondary((id \ + 18040)(content(Whitespace\" \"))))(Tile((id \ + 18041)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18042)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18044)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18047)(content(Whitespace\" \")))))))))(Secondary((id \ + 18049)(content(Whitespace\" \"))))(Secondary((id \ + 18072)(content(Comment\"#err: incons with \ + arrow#\"))))(Secondary((id \ + 18073)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18077)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18078)(content(Whitespace\" \"))))(Tile((id \ + 18080)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18081)(content(Whitespace\" \")))))((Secondary((id \ + 18083)(content(Whitespace\" \"))))(Tile((id \ + 18092)(label(Undefined))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18093)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18095)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18098)(content(Whitespace\" \")))))))))(Secondary((id \ + 18100)(content(Whitespace\" \"))))(Secondary((id \ + 18120)(content(Comment\"#err: cons \ + undefined#\"))))(Secondary((id \ + 18121)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18125)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18126)(content(Whitespace\" \"))))(Tile((id \ + 18128)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18129)(content(Whitespace\" \")))))((Secondary((id \ + 18131)(content(Whitespace\" \"))))(Tile((id \ + 18132)(label(B))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18133)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18138)(label(\"\\\"lol\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18141)(content(Whitespace\" \")))))))))(Secondary((id \ + 18143)(content(Whitespace\" \"))))(Secondary((id \ + 18160)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18161)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18165)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18166)(content(Whitespace\" \"))))(Tile((id \ + 18168)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18169)(content(Whitespace\" \"))))(Tile((id \ + 18170)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18172)(content(Whitespace\" \"))))(Secondary((id \ + 18173)(content(Whitespace\" \"))))(Grout((id 18175)(shape \ + Convex)))(Tile((id 18174)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18177)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18178)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18183)(label(Bool))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18184)(content(Whitespace\" \")))))((Secondary((id \ + 18186)(content(Whitespace\" \"))))(Tile((id \ + 18188)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18191)(content(Whitespace\" \")))))))))(Secondary((id \ + 18193)(content(Whitespace\" \"))))(Secondary((id \ + 18210)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18211)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18215)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18216)(content(Whitespace\" \"))))(Tile((id \ + 18218)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18219)(content(Whitespace\" \"))))(Tile((id \ + 18220)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18222)(content(Whitespace\" \"))))(Secondary((id \ + 18223)(content(Whitespace\" \"))))(Grout((id 18225)(shape \ + Convex)))(Tile((id 18224)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18227)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18228)(content(Whitespace\" \")))))((Secondary((id \ + 18230)(content(Whitespace\" \"))))(Tile((id \ + 18232)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18233)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18238)(label(\"\\\"lol\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18241)(content(Whitespace\" \")))))))))(Secondary((id \ + 18243)(content(Whitespace\" \"))))(Secondary((id \ + 18260)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18261)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18265)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18266)(content(Whitespace\" \"))))(Tile((id \ + 18268)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18269)(content(Whitespace\" \"))))(Tile((id \ + 18270)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18272)(content(Whitespace\" \"))))(Secondary((id \ + 18273)(content(Whitespace\" \"))))(Grout((id 18275)(shape \ + Convex)))(Tile((id 18274)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18278)(label(One))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18279)(content(Whitespace\" \")))))((Secondary((id \ + 18281)(content(Whitespace\" \"))))(Tile((id \ + 18283)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18284)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18286)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18289)(content(Whitespace\" \")))))))))(Secondary((id \ + 18291)(content(Whitespace\" \"))))(Secondary((id \ + 18308)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18309)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18310)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18361)(content(Comment\"#pat tests: happy (but refutable \ + patterns so weird)#\"))))(Secondary((id \ + 18362)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18366)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18367)(content(Whitespace\" \"))))(Tile((id \ + 18370)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18371)(content(Whitespace\" \")))))((Secondary((id \ + 18373)(content(Whitespace\" \"))))(Tile((id \ + 18375)(label(Bo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18378)(content(Whitespace\" \")))))))))(Secondary((id \ + 18380)(content(Whitespace\" \"))))(Secondary((id \ + 18401)(content(Comment\"#kind of a weird \ + edge#\"))))(Secondary((id \ + 18402)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18406)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18407)(content(Whitespace\" \"))))(Tile((id \ + 18410)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18411)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18413)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18414)(content(Whitespace\" \")))))((Secondary((id \ + 18416)(content(Whitespace\" \"))))(Tile((id \ + 18420)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18421)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18426)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18429)(content(Whitespace\" \")))))))))(Secondary((id \ + 18431)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18435)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18436)(content(Whitespace\" \"))))(Tile((id \ + 18439)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18440)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18442)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 18443)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18445)(content(Whitespace\" \"))))(Tile((id \ + 18451)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18452)(content(Whitespace\" \")))))((Secondary((id \ + 18454)(content(Whitespace\" \"))))(Tile((id \ + 18456)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18457)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18459)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18462)(content(Whitespace\" \")))))))))(Secondary((id \ + 18464)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18468)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18469)(content(Whitespace\" \"))))(Tile((id \ + 18472)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18473)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18475)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 18476)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18478)(content(Whitespace\" \"))))(Secondary((id \ + 18479)(content(Whitespace\" \"))))(Grout((id 18481)(shape \ + Convex)))(Tile((id 18480)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18483)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18484)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18488)(label(Int))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18489)(content(Whitespace\" \")))))((Secondary((id \ + 18491)(content(Whitespace\" \"))))(Tile((id \ + 18493)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18494)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18496)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18499)(content(Whitespace\" \")))))))))(Secondary((id \ + 18501)(content(Whitespace\" \"))))(Secondary((id \ + 18502)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18506)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18507)(content(Whitespace\" \"))))(Tile((id \ + 18510)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18511)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18513)(content(Whitespace\" \"))))(Secondary((id \ + 18514)(content(Whitespace\" \"))))(Grout((id 18516)(shape \ + Convex)))(Tile((id 18515)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18518)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18519)(content(Whitespace\" \")))))((Secondary((id \ + 18521)(content(Whitespace\" \"))))(Tile((id \ + 18523)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18526)(content(Whitespace\" \")))))))))(Secondary((id \ + 18528)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18529)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 18547)(content(Comment\"#pat tests: \ + errors#\"))))(Secondary((id \ + 18548)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18552)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18553)(content(Whitespace\" \"))))(Tile((id \ + 18555)(label(2))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18556)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18558)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18559)(content(Whitespace\" \")))))((Secondary((id \ + 18561)(content(Whitespace\" \"))))(Tile((id \ + 18562)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18565)(content(Whitespace\" \")))))))))(Secondary((id \ + 18567)(content(Whitespace\" \"))))(Secondary((id \ + 18590)(content(Comment\"#err: incons with \ + arrow#\"))))(Secondary((id \ + 18591)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18595)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18596)(content(Whitespace\" \"))))(Tile((id \ + 18607)(label(NotDefined))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18608)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18610)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18611)(content(Whitespace\" \")))))((Secondary((id \ + 18613)(content(Whitespace\" \"))))(Tile((id \ + 18614)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18617)(content(Whitespace\" \")))))))))(Secondary((id \ + 18619)(content(Whitespace\" \"))))(Secondary((id \ + 18639)(content(Comment\"#err: cons \ + undefined#\"))))(Secondary((id \ + 18640)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18644)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18645)(content(Whitespace\" \"))))(Tile((id \ + 18648)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18649)(content(Whitespace\" \")))))((Secondary((id \ + 18651)(content(Whitespace\" \"))))(Tile((id \ + 18655)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18658)(content(Whitespace\" \")))))))))(Secondary((id \ + 18660)(content(Whitespace\" \"))))(Secondary((id \ + 18677)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18678)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18682)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18683)(content(Whitespace\" \"))))(Tile((id \ + 18686)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18687)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18692)(label(true))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18693)(content(Whitespace\" \")))))((Secondary((id \ + 18695)(content(Whitespace\" \"))))(Tile((id \ + 18699)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18700)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18705)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18708)(content(Whitespace\" \")))))))))(Secondary((id \ + 18710)(content(Whitespace\" \"))))(Secondary((id \ + 18727)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18728)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18732)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18733)(content(Whitespace\" \"))))(Tile((id \ + 18736)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18737)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18739)(content(Whitespace\" \"))))(Tile((id \ + 18745)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18746)(content(Whitespace\" \")))))((Secondary((id \ + 18748)(content(Whitespace\" \"))))(Tile((id \ + 18750)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18751)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18753)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18756)(content(Whitespace\" \")))))))))(Secondary((id \ + 18758)(content(Whitespace\" \"))))(Secondary((id \ + 18775)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18776)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18780)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18781)(content(Whitespace\" \"))))(Tile((id \ + 18784)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18785)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18787)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 18788)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18790)(content(Whitespace\" \"))))(Secondary((id \ + 18791)(content(Whitespace\" \"))))(Grout((id 18793)(shape \ + Convex)))(Tile((id 18792)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18795)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 18796)(content(Whitespace\" \")))))((Secondary((id \ + 18798)(content(Whitespace\" \"))))(Tile((id \ + 18800)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 18803)(content(Whitespace\" \")))))))))(Secondary((id \ + 18805)(content(Whitespace\" \"))))(Secondary((id \ + 18822)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18823)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18827)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 18828)(content(Whitespace\" \"))))(Tile((id \ + 18831)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18832)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18834)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 18835)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 18837)(content(Whitespace\" \"))))(Secondary((id \ + 18838)(content(Whitespace\" \"))))(Grout((id 18840)(shape \ + Convex)))(Tile((id 18839)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18842)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 18843)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 18848)(label(Bool))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 18849)(content(Whitespace\" \")))))((Secondary((id \ + 18851)(content(Whitespace\" \"))))(Tile((id \ + 18853)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 18854)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 18859)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 18862)(content(Whitespace\" \")))))))))(Secondary((id \ + 18864)(content(Whitespace\" \"))))(Secondary((id \ + 18881)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 18882)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 18899)(label(\"\\\"Thats all, folks\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 18900)(content(Whitespace\"\\226\\143\\142\")))))()))(ancestors())))(caret \ + Outer))"; + backup_text = + "#Non-recursive sum/alias tests#\n\ + #all lines with trailing err comment should have 1 error#\n\ + #no other lines should have errors#\n\n\ + #type definitions: no errors#\n\ + type = in\n\ + \ type SingleNull = +One in\n\ + \ type Single = +F(Int) in\n\ + \ type GoodSum = A + B + C(Int) in\n\ + \ type Partial = Ok( ) + in\n\ + \ type DoubleAlias = GoodSum in\n\ + \ type VerticalLeading =\n\ + \ + A\n\ + + B(GoodSum)\n\ + + C(Bool->Bool) \n\ + \ in\n\n\ + #incorrect or incomplete type definitions#\n\ + \ type badTypeName = in #err: invalid type name#\n\ + \ type ( , ) = in #err: invalid type name#\n\ + \ type = badTypeToken in #err: invalid type token#\n\ + \ type NotASum = NotInSum(Bool) in #err: cons not in sum#\n\ + \ type Bool = in #err: shadows base type#\n\ + \ type Dupes =\n\ + \ + Guy(Bool) #no err#\n\ + + Guy(Int) #err: already used#\n\ + + Guy in #err: already used#\n\ + \ type BadCons =\n\ + \ + Um(Unbound) #err: unbound type var#\n\ + + invalid #err: invalid#\n\ + + Bool #err: expected cons found type#\n\ + + Int(Int) #err: expected cons found type#\n\ + + ( )(Int) #err: expected cons found type#\n\ + + A(Bool)(Int) in #err: expected cons found app#\n\n\ + #nested sum defs dont add tags to scope#\n\ + \ type NestedAlias = (Int, Anonymous + Sum) in \n\ + \ let x:NestedAlias = (1, Sum) in #err: not defined#\n\n\ + #unbound tyvars treated as unknown-typehole#\n\ + let a:Bad = 0 in a == 0; #err: not bound#\n\n\ + #non-sum-types cant be recursive#\n\ + type Lol = Lol in #err: not bound#\n\n\ + #no errors: analytic shadowing#\n\ + \ type Tork1 = +Blob in\n\ + \ type Tork2 = +Blob in \n\ + \ let x:Tork1 = Blob in\n\n\ + #exp tests: happy#\n\ + type YoDawg = Yo(Int) + Bo(Int)+ Dawg(Bool) in\n\ + \ let _ = Yo(1) in\n\ + let _ : YoDawg = Yo(2) in\n\ + let _ : +Yo(Bool) = Yo(true) in\n\ + let _ : (Yo + Dawg, Int) = (Dawg,5) in\n\ + let _ : DoubleAlias = C(4) in\n\n\ + #exp tests: errors#\n\ + let _ = 2(1) in #err: incons with arrow#\n\ + let _ = Undefined(1) in #err: cons undefined#\n\ + let _ = B(\"lol\") in #err: type incons#\n\ + let _ : +Yo(Bool) = Yo in #err: type incons#\n\ + let _ : +Yo = Yo(\"lol\") in #err: type incons#\n\ + let _ : +One = Yo(1) in #err: type incons#\n\n\ + #pat tests: happy (but refutable patterns so weird)#\n\ + let Yo = Bo in #kind of a weird edge#\n\ + let Yo(1) = Dawg(true) in\n\ + let Yo(1): YoDawg = Yo(1) in\n\ + let Yo(1): +Yo(Int) = Yo(1) in \n\ + let Yo: +Yo = Yo in\n\n\ + #pat tests: errors#\n\ + let 2(1) = 3 in #err: incons with arrow#\n\ + let NotDefined(1) = 3 in #err: cons undefined#\n\ + let Yo = Dawg in #err: type incons#\n\ + let Yo(true) = Dawg(true) in #err: type incons#\n\ + let Yo: YoDawg = Yo(1) in #err: type incons#\n\ + let Yo(1): +Yo = Yo in #err: type incons#\n\ + let Yo(1): +Yo(Bool) = Yo(true) in #err: type incons#\n\ + \"Thats all, folks\"\n"; + } ); + ( 552, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Tile((id \ + 521)(label(step))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 522)(content(Whitespace\" \"))))(Secondary((id \ + 523)(content(Whitespace\" \"))))(Secondary((id \ + 524)(content(Whitespace\" \"))))(Tile((id \ + 525)(label(*))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 527)(content(Whitespace\" \"))))(Secondary((id \ + 528)(content(Whitespace\" \"))))(Secondary((id \ + 529)(content(Whitespace\" \"))))(Tile((id \ + 531)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 532)(content(Whitespace\" \"))))(Secondary((id \ + 533)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 536)(shape Concave)))(Tile((id 535)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 537)(content(Whitespace\" \"))))(Tile((id \ + 538)(label(*))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 540)(content(Whitespace\" \"))))(Tile((id \ + 541)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 542)(content(Whitespace\" \"))))(Tile((id \ + 543)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 545)(content(Whitespace\" \"))))(Tile((id \ + 546)(label(4))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 547)(content(Whitespace\" \"))))(Tile((id \ + 548)(label(*))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 550)(content(Whitespace\" \"))))(Tile((id \ + 551)(label(5))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))()))(ancestors())))(caret \ + Outer))"; + backup_text = "step * in \n 2 * 3 + 4 * 5"; + } ); + ( 810, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Tile((id \ + 682)(label(type))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Grout((id 685)(shape \ + Concave)))(Tile((id 688)(label(Test))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 689)(content(Whitespace\" \"))))(Tile((id \ + 690)(label(=))(mold((out Any)(in_())(nibs(((shape(Concave \ + 8))(sort Any))((shape(Concave 8))(sort \ + Any))))))(shards(0))(children())))(Secondary((id \ + 692)(content(Whitespace\" \"))))(Secondary((id \ + 693)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 695)(shape Convex)))(Tile((id 694)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 5))(sort \ + Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 696)(content(Whitespace\" \"))))(Tile((id \ + 697)(label(A))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 698)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 702)(label(Int))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 703)(content(Whitespace\" \"))))(Secondary((id \ + 704)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 705)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 707)(content(Whitespace\" \"))))(Tile((id \ + 708)(label(B))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 709)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 710)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 712)(content(Whitespace\" \"))))(Tile((id \ + 713)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 714)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 720)(label(Float))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 721)(content(Whitespace\" \"))))(Secondary((id \ + 722)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 724)(shape Concave)))(Tile((id 725)(label(in))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 726)(content(Whitespace\" \"))))(Secondary((id \ + 727)(content(Whitespace\"\\226\\143\\142\"))))(Grout((id \ + 729)(shape Concave)))(Tile((id 732)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 733)(content(Whitespace\" \ + \"))))(Tile((id 735)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 736)(content(Whitespace\" \"))))(Tile((id \ + 737)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 739)(content(Whitespace\" \"))))(Tile((id \ + 743)(label(Test))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 744)(content(Whitespace\" \")))))((Secondary((id \ + 746)(content(Whitespace\" \"))))(Tile((id \ + 747)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 748)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 752)(label(7.7))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 755)(content(Whitespace\" \")))))))))(Secondary((id \ + 757)(content(Whitespace\" \"))))(Secondary((id \ + 758)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 763)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 764)(content(Whitespace\" \ + \"))))(Tile((id 766)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 767)(content(Whitespace\" \"))))(Secondary((id \ + 768)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 769)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 771)(content(Whitespace\" \ + \"))))(Tile((id 772)(label(A))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 773)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 775)(label(n))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 776)(content(Whitespace\" \")))))))))(Secondary((id \ + 779)(content(Whitespace\" \"))))(Tile((id \ + 780)(label(n))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 781)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 782)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 784)(content(Whitespace\" \ + \"))))(Tile((id 785)(label(B))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 786)(content(Whitespace\" \")))))))))(Secondary((id \ + 789)(content(Whitespace\" \"))))(Tile((id \ + 790)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 791)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 792)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 794)(content(Whitespace\" \ + \"))))(Tile((id 795)(label(C))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 796)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 798)(label(n))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 799)(content(Whitespace\" \")))))))))(Secondary((id \ + 802)(content(Whitespace\" \"))))(Tile((id \ + 803)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 807)(content(Whitespace\" \"))))(Secondary((id \ + 804)(content(Whitespace\" \"))))(Secondary((id \ + 805)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 809)(content(Whitespace\" \")))))()))(ancestors())))(caret \ + Outer))"; + backup_text = + "type Test = \n\ + \ + A(Int) \n\ + + B\n\ + + C(Float) \n\ + \ in \n\ + \ let x : Test = C(7.7) in \n\ + case x \n\ + | A(n) => n\n\ + | B => 2\n\ + | C(n) => 3 \n\ + end "; + } ); + ( 4, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 2)(content(Whitespace\" \"))))(Secondary((id \ + 3)(content(Whitespace\" \")))))((Grout((id 0)(shape \ + Convex))))))(ancestors())))(caret Outer))"; + backup_text = " "; + } ); + ( 4, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 2)(content(Whitespace\" \"))))(Secondary((id \ + 3)(content(Whitespace\" \")))))((Grout((id 0)(shape \ + Convex))))))(ancestors())))(caret Outer))"; + backup_text = " "; + } ); + ( 4, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 2)(content(Whitespace\" \"))))(Secondary((id \ + 3)(content(Whitespace\" \")))))((Grout((id 0)(shape \ + Convex))))))(ancestors())))(caret Outer))"; + backup_text = " "; + } ); + ] ); + examples = + ( "Introduction", + [ + ( "Introduction", + ( 16872, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 14750)(content(Comment\"# Welcome to Hazel! \ + #\"))))(Secondary((id \ + 15734)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 15735)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16048)(content(Comment\"# To get started, type 2 * 3 + 4 \ + into the hole below, #\"))))(Secondary((id \ + 15875)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16071)(content(Comment\"# stopping between each character \ + to observe how holes #\"))))(Secondary((id \ + 15941)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16868)(content(Comment\"# appear at each step to ensure \ + that every editor state #\"))))(Secondary((id \ + 16170)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16187)(content(Comment\"# is meaningful. \ + #\"))))(Secondary((id \ + 15830)(content(Whitespace\"\\226\\143\\142\")))))((Grout((id \ + 16871)(shape Convex)))(Secondary((id \ + 16009)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16010)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16295)(content(Comment\"# Once you are finished, navigate \ + the menu in the top bar #\"))))(Secondary((id \ + 16296)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16369)(content(Comment\"# to see other examples, enter \ + Scratch mode to play with #\"))))(Secondary((id \ + 16370)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16427)(content(Comment\"# Hazel, or enter Exercises mode to \ + do some introductory #\"))))(Secondary((id \ + 16428)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16650)(content(Comment\"# exercises. Hazel is a \ + work-in-progress research project, #\"))))(Secondary((id \ + 16569)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16793)(content(Comment\"# so there is not much public \ + educational material yet. #\"))))(Secondary((id \ + 16669)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16805)(content(Comment\"# Check out the research papers at \ + hazel.org for more on #\"))))(Secondary((id \ + 16745)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16766)(content(Comment\"# how Hazel works. \ + #\")))))))(ancestors())))(caret Outer))"; + backup_text = + "# Welcome to Hazel! #\n\n\ + # To get started, type 2 * 3 + 4 into the hole below, #\n\ + # stopping between each character to observe how holes #\n\ + # appear at each step to ensure that every editor state #\n\ + # is meaningful. #\n\ + \ \n\n\ + # Once you are finished, navigate the menu in the top bar #\n\ + # to see other examples, enter Scratch mode to play with #\n\ + # Hazel, or enter Exercises mode to do some introductory #\n\ + # exercises. Hazel is a work-in-progress research project, #\n\ + # so there is not much public educational material yet. #\n\ + # Check out the research papers at hazel.org for more on #\n\ + # how Hazel works. #"; + } ) ); + ( "Basic Reference", + ( 13633, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 1674)(content(Whitespace\" \"))))(Tile((id \ + 1685)(label(float_lits))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1686)(content(Whitespace\" \")))))((Tile((id \ + 1687)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1689)(content(Whitespace\" \"))))(Tile((id \ + 1694)(label(Float))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1695)(content(Whitespace\" \")))))))(ancestors((((id \ + 1673)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards((0)(1 \ + 2)))(children(()(((Secondary((id 1698)(content(Whitespace\" \ + \"))))(Tile((id 1701)(label(1.5))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1704)(content(Whitespace\" \")))))))))(((Secondary((id \ + 2915)(content(Comment\"# Hazel Language Quick Reference \ + #\"))))(Secondary((id \ + 3020)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3021)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3150)(content(Comment\"# Empty holes stand for missing \ + expressions, patterns, or types #\"))))(Secondary((id \ + 3030)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3035)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3036)(content(Whitespace\" \"))))(Tile((id \ + 3047)(label(empty_hole))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 3048)(content(Whitespace\" \")))))((Secondary((id \ + 3052)(content(Whitespace\" \"))))(Grout((id 3051)(shape \ + Convex)))(Secondary((id 3050)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 3151)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3152)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2840)(content(Comment\"# Integers #\"))))(Secondary((id \ + 2829)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1498)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1499)(content(Whitespace\" \"))))(Tile((id \ + 1508)(label(int_lits))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1509)(content(Whitespace\" \"))))(Tile((id \ + 1510)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1512)(content(Whitespace\" \"))))(Tile((id \ + 1515)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1516)(content(Whitespace\" \")))))((Secondary((id \ + 1519)(content(Whitespace\" \"))))(Tile((id \ + 1520)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1523)(content(Whitespace\" \")))))))))(Secondary((id \ + 1525)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1530)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1531)(content(Whitespace\" \"))))(Tile((id \ + 1540)(label(negation))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1541)(content(Whitespace\" \")))))((Secondary((id \ + 1544)(content(Whitespace\" \"))))(Tile((id \ + 1545)(label(-))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 2))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1546)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1549)(content(Whitespace\" \")))))))))(Secondary((id \ + 1551)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1556)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1557)(content(Whitespace\" \"))))(Tile((id \ + 1568)(label(arithmetic))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1569)(content(Whitespace\" \")))))((Secondary((id \ + 1572)(content(Whitespace\" \"))))(Tile((id \ + 1573)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1574)(label(*))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1576)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1577)(content(Whitespace\" \"))))(Tile((id \ + 1578)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1580)(content(Whitespace\" \"))))(Tile((id \ + 1581)(label(8))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1582)(label(/))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1584)(label(4))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1587)(content(Whitespace\" \")))))))))(Secondary((id \ + 1589)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1594)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1595)(content(Whitespace\" \"))))(Tile((id \ + 1610)(label(int_comparison))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1611)(content(Whitespace\" \")))))((Secondary((id \ + 1614)(content(Whitespace\" \"))))(Tile((id \ + 1615)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1617)(label(10))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1618)(content(Whitespace\" \"))))(Tile((id \ + 1621)(label(==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1622)(content(Whitespace\" \"))))(Tile((id \ + 1624)(label(10))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1625)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1627)(content(Whitespace\" \"))))(Tile((id \ + 1628)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1629)(content(Whitespace\" \"))))(Tile((id \ + 1630)(label(<))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1632)(content(Whitespace\" \"))))(Tile((id \ + 1633)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1634)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1636)(content(Whitespace\" \"))))(Tile((id \ + 1637)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1638)(content(Whitespace\" \"))))(Tile((id \ + 1641)(label(<=))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1642)(content(Whitespace\" \"))))(Tile((id \ + 1643)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1644)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1646)(content(Whitespace\" \"))))(Tile((id \ + 1647)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1648)(content(Whitespace\" \"))))(Tile((id \ + 1649)(label(>))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1651)(content(Whitespace\" \"))))(Tile((id \ + 1652)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1653)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1655)(content(Whitespace\" \"))))(Tile((id \ + 1656)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1657)(content(Whitespace\" \"))))(Tile((id \ + 1660)(label(>=))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1661)(content(Whitespace\" \"))))(Tile((id \ + 1662)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1665)(content(Whitespace\" \")))))))))(Secondary((id \ + 3353)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2841)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2866)(content(Comment\"# Floating Point Numbers \ + #\"))))(Secondary((id \ + 1669)(content(Whitespace\"\\226\\143\\142\")))))((Secondary((id \ + 1706)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1711)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1712)(content(Whitespace\" \"))))(Tile((id \ + 1724)(label(float_artih))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1725)(content(Whitespace\" \")))))((Secondary((id \ + 1728)(content(Whitespace\" \"))))(Tile((id \ + 1730)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1731)(content(Whitespace\" \"))))(Tile((id \ + 1734)(label(*.))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1735)(content(Whitespace\" \"))))(Tile((id \ + 1737)(label(2.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1738)(content(Whitespace\" \"))))(Tile((id \ + 1741)(label(+.))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1742)(content(Whitespace\" \"))))(Tile((id \ + 1744)(label(8.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1745)(content(Whitespace\" \"))))(Tile((id \ + 1748)(label(/.))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1749)(content(Whitespace\" \"))))(Tile((id \ + 1751)(label(4.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1754)(content(Whitespace\" \")))))))))(Secondary((id \ + 1756)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1761)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1762)(content(Whitespace\" \"))))(Tile((id \ + 1779)(label(float_comparison))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1780)(content(Whitespace\" \")))))((Secondary((id \ + 1783)(content(Whitespace\" \"))))(Tile((id \ + 1784)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1787)(label(10.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1788)(content(Whitespace\" \"))))(Tile((id \ + 1792)(label(==.))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1793)(content(Whitespace\" \"))))(Tile((id \ + 1796)(label(10.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1797)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1799)(content(Whitespace\" \"))))(Tile((id \ + 1801)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1802)(content(Whitespace\" \"))))(Tile((id \ + 1805)(label(<.))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1806)(content(Whitespace\" \"))))(Tile((id \ + 1808)(label(2.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1809)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1811)(content(Whitespace\" \"))))(Tile((id \ + 1813)(label(2.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1814)(content(Whitespace\" \"))))(Tile((id \ + 1818)(label(<=.))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1819)(content(Whitespace\" \"))))(Tile((id \ + 1821)(label(3.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1822)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1824)(content(Whitespace\" \"))))(Tile((id \ + 1826)(label(3.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1827)(content(Whitespace\" \"))))(Tile((id \ + 1830)(label(>.))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1831)(content(Whitespace\" \"))))(Tile((id \ + 1833)(label(2.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1834)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1836)(content(Whitespace\" \"))))(Tile((id \ + 1838)(label(2.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1839)(content(Whitespace\" \"))))(Tile((id \ + 1843)(label(>=.))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1844)(content(Whitespace\" \"))))(Tile((id \ + 13632)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1849)(content(Whitespace\" \")))))))))(Secondary((id \ + 1851)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2867)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2878)(content(Comment\"# Booleans #\"))))(Secondary((id \ + 1853)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1857)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1858)(content(Whitespace\" \"))))(Tile((id \ + 1867)(label(booleans))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1868)(content(Whitespace\" \"))))(Tile((id \ + 1869)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1871)(content(Whitespace\" \"))))(Tile((id \ + 1872)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 1876)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1877)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1879)(content(Whitespace\" \"))))(Tile((id \ + 1883)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 1884)(content(Whitespace\" \")))))((Secondary((id \ + 1887)(content(Whitespace\" \"))))(Tile((id \ + 1888)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1892)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1893)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1895)(content(Whitespace\" \"))))(Tile((id \ + 1900)(label(false))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1903)(content(Whitespace\" \")))))))))(Secondary((id \ + 1905)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1910)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1911)(content(Whitespace\" \"))))(Tile((id \ + 1924)(label(conditionals))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1925)(content(Whitespace\" \")))))((Secondary((id \ + 1928)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1932)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1933)(content(Whitespace\" \"))))(Tile((id \ + 1935)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1936)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1937)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1939)(content(Whitespace\" \"))))(Tile((id \ + 1940)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1941)(content(Whitespace\" \")))))((Secondary((id \ + 1944)(content(Whitespace\" \"))))(Tile((id \ + 1945)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1946)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1947)(content(Whitespace\" \"))))(Tile((id \ + 1948)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1950)(content(Whitespace\" \"))))(Tile((id \ + 1951)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1952)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1954)(content(Whitespace\" \"))))(Tile((id \ + 1955)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1956)(content(Whitespace\" \"))))(Tile((id \ + 1957)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1959)(content(Whitespace\" \"))))(Tile((id \ + 1960)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1963)(content(Whitespace\" \")))))))))(Secondary((id \ + 1965)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1969)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1970)(content(Whitespace\" \"))))(Tile((id \ + 1972)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1973)(content(Whitespace\" \"))))(Tile((id \ + 1974)(label(>))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1976)(content(Whitespace\" \"))))(Tile((id \ + 1977)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1980)(content(Whitespace\" \")))))((Secondary((id \ + 1984)(content(Whitespace\" \"))))(Tile((id \ + 1986)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1991)(content(Whitespace\" \"))))(Secondary((id \ + 1987)(content(Whitespace\" \"))))(Secondary((id \ + 1988)(content(Whitespace\" \"))))(Secondary((id \ + 1989)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 1995)(content(Whitespace\" \"))))(Tile((id \ + 1997)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2002)(content(Whitespace\" \"))))(Secondary((id \ + 1998)(content(Whitespace\" \"))))(Secondary((id \ + 1999)(content(Whitespace\" \"))))(Secondary((id \ + 2000)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2004)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2916)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2925)(content(Comment\"# Tuples #\"))))(Secondary((id \ + 2006)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2010)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2011)(content(Whitespace\" \"))))(Tile((id \ + 2018)(label(tuples))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2019)(content(Whitespace\" \"))))(Tile((id \ + 2020)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2022)(content(Whitespace\" \"))))(Tile((id \ + 2023)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2026)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2027)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2029)(content(Whitespace\" \"))))(Tile((id \ + 2033)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2034)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2036)(content(Whitespace\" \"))))(Tile((id \ + 2037)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2041)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2042)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2044)(content(Whitespace\" \"))))(Tile((id \ + 2047)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + 2048)(content(Whitespace\" \")))))((Secondary((id \ + 2051)(content(Whitespace\" \"))))(Tile((id \ + 2052)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2053)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2054)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2056)(content(Whitespace\" \"))))(Tile((id \ + 2060)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2061)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2063)(content(Whitespace\" \"))))(Tile((id \ + 2064)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2069)(label(false))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2070)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2072)(content(Whitespace\" \"))))(Tile((id \ + 2073)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 2076)(content(Whitespace\" \")))))))))(Secondary((id \ + 2078)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2083)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2084)(content(Whitespace\" \"))))(Tile((id \ + 2086)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2087)(label(a))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2088)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2090)(content(Whitespace\" \"))))(Tile((id \ + 2091)(label(b))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2092)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2094)(content(Whitespace\" \"))))(Tile((id \ + 2095)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2096)(label(c))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2097)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2099)(content(Whitespace\" \"))))(Tile((id \ + 2100)(label(d))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))))))))))))(Secondary((id \ + 2101)(content(Whitespace\" \")))))((Secondary((id \ + 2104)(content(Whitespace\" \"))))(Tile((id \ + 2110)(label(tuples))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2113)(content(Whitespace\" \")))))))))(Secondary((id \ + 2115)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2926)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2938)(content(Comment\"# Functions #\"))))(Secondary((id \ + 2117)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2121)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2122)(content(Whitespace\" \"))))(Tile((id \ + 2124)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2125)(content(Whitespace\" \"))))(Tile((id \ + 2126)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2128)(content(Whitespace\" \"))))(Tile((id \ + 2129)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2132)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2133)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2135)(content(Whitespace\" \"))))(Tile((id \ + 2138)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2139)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2141)(content(Whitespace\" \"))))(Tile((id \ + 2144)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2145)(content(Whitespace\" \"))))(Tile((id \ + 2148)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2149)(content(Whitespace\" \"))))(Tile((id \ + 2152)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2153)(content(Whitespace\" \")))))((Secondary((id \ + 2156)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2160)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 2161)(content(Whitespace\" \"))))(Tile((id \ + 2163)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2164)(label(m))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2165)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2167)(content(Whitespace\" \"))))(Tile((id \ + 2168)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2169)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2171)(content(Whitespace\" \"))))(Tile((id \ + 2172)(label(b))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 2173)(content(Whitespace\" \")))))))))(Secondary((id \ + 2177)(content(Whitespace\" \"))))(Tile((id \ + 2178)(label(m))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2179)(content(Whitespace\" \"))))(Tile((id \ + 2180)(label(*))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 4))(sort Exp))((shape(Concave 4))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2182)(content(Whitespace\" \"))))(Tile((id \ + 2183)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2184)(content(Whitespace\" \"))))(Tile((id \ + 2185)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2187)(content(Whitespace\" \"))))(Tile((id \ + 2188)(label(b))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2193)(content(Whitespace\" \"))))(Secondary((id \ + 2189)(content(Whitespace\" \"))))(Secondary((id \ + 2190)(content(Whitespace\" \"))))(Secondary((id \ + 2191)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2195)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2939)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2998)(content(Comment\"# Recursive Functions (arrow type \ + annotation required) #\"))))(Secondary((id \ + 2197)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2201)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2202)(content(Whitespace\" \"))))(Tile((id \ + 2221)(label(double_recursively))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2222)(content(Whitespace\" \"))))(Tile((id \ + 2223)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2225)(content(Whitespace\" \"))))(Tile((id \ + 2228)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2229)(content(Whitespace\" \"))))(Tile((id \ + 2232)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2233)(content(Whitespace\" \"))))(Tile((id \ + 2236)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2237)(content(Whitespace\" \")))))((Secondary((id \ + 2240)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2244)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 2245)(content(Whitespace\" \"))))(Tile((id \ + 2247)(label(n))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2248)(content(Whitespace\" \")))))))))(Secondary((id \ + 2252)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2255)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2256)(content(Whitespace\" \"))))(Tile((id \ + 2258)(label(n))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2259)(content(Whitespace\" \"))))(Tile((id \ + 2262)(label(==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2263)(content(Whitespace\" \"))))(Tile((id \ + 2264)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2267)(content(Whitespace\" \")))))((Secondary((id \ + 2271)(content(Whitespace\" \"))))(Tile((id \ + 2273)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2278)(content(Whitespace\" \"))))(Secondary((id \ + 2274)(content(Whitespace\" \"))))(Secondary((id \ + 2275)(content(Whitespace\" \"))))(Secondary((id \ + 2276)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2282)(content(Whitespace\" \"))))(Tile((id \ + 2301)(label(double_recursively))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 2302)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2304)(label(n))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2305)(content(Whitespace\" \"))))(Tile((id \ + 2306)(label(-))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2308)(content(Whitespace\" \"))))(Tile((id \ + 2309)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2310)(content(Whitespace\" \"))))(Tile((id \ + 2311)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2313)(content(Whitespace\" \"))))(Tile((id \ + 2314)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2319)(content(Whitespace\" \"))))(Secondary((id \ + 2315)(content(Whitespace\" \"))))(Secondary((id \ + 2316)(content(Whitespace\" \"))))(Secondary((id \ + 2317)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2321)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2999)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3007)(content(Comment\"# Lists #\"))))(Secondary((id \ + 2323)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2327)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2328)(content(Whitespace\" \"))))(Tile((id \ + 2339)(label(empty_list))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2340)(content(Whitespace\" \"))))(Tile((id \ + 2341)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2343)(content(Whitespace\" \"))))(Tile((id 2344)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2347)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2348)(content(Whitespace\" \")))))((Secondary((id \ + 2351)(content(Whitespace\" \"))))(Tile((id \ + 2354)(label([]))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2357)(content(Whitespace\" \")))))))))(Secondary((id \ + 2359)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2364)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2365)(content(Whitespace\" \"))))(Tile((id \ + 2380)(label(non_empty_list))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2381)(content(Whitespace\" \"))))(Tile((id \ + 2382)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2384)(content(Whitespace\" \"))))(Tile((id 2385)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2388)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2389)(content(Whitespace\" \")))))((Secondary((id \ + 2392)(content(Whitespace\" \"))))(Tile((id \ + 2393)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2396)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2397)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2400)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2401)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2404)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2407)(label([]))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2410)(content(Whitespace\" \")))))))))(Secondary((id \ + 2412)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2417)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2418)(content(Whitespace\" \"))))(Tile((id \ + 2432)(label(list_literals))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2433)(content(Whitespace\" \"))))(Tile((id \ + 2434)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2436)(content(Whitespace\" \"))))(Tile((id 2437)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2440)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2441)(content(Whitespace\" \")))))((Secondary((id \ + 2444)(content(Whitespace\" \"))))(Tile((id 2445)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2446)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 2447)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2449)(content(Whitespace\" \"))))(Tile((id \ + 2450)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2451)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2453)(content(Whitespace\" \"))))(Tile((id \ + 2454)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2457)(content(Whitespace\" \")))))))))(Secondary((id \ + 2459)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2464)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2465)(content(Whitespace\" \"))))(Tile((id \ + 2472)(label(length))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2473)(content(Whitespace\" \"))))(Tile((id \ + 2474)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2476)(content(Whitespace\" \"))))(Tile((id 2477)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2480)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2481)(content(Whitespace\" \"))))(Tile((id \ + 2484)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2485)(content(Whitespace\" \"))))(Tile((id \ + 2488)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2489)(content(Whitespace\" \")))))((Secondary((id \ + 2492)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2496)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 2497)(content(Whitespace\" \"))))(Tile((id \ + 2500)(label(xs))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2501)(content(Whitespace\" \")))))))))(Secondary((id \ + 2505)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2510)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2511)(content(Whitespace\" \ + \"))))(Tile((id 2514)(label(xs))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2515)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2516)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2518)(content(Whitespace\" \ + \"))))(Tile((id 2521)(label([]))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2522)(content(Whitespace\" \")))))))))(Secondary((id \ + 2525)(content(Whitespace\" \"))))(Tile((id \ + 2526)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2527)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2528)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2530)(content(Whitespace\" \ + \"))))(Tile((id 2532)(label(hd))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 2535)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 6))(sort Pat))((shape(Concave 6))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2537)(label(tl))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2538)(content(Whitespace\" \")))))))))(Secondary((id \ + 2541)(content(Whitespace\" \"))))(Tile((id \ + 2542)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2543)(content(Whitespace\" \"))))(Tile((id \ + 2544)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2546)(content(Whitespace\" \"))))(Tile((id \ + 2552)(label(length))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2553)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2556)(label(tl))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2561)(content(Whitespace\" \"))))(Secondary((id \ + 2557)(content(Whitespace\" \"))))(Secondary((id \ + 2558)(content(Whitespace\" \"))))(Secondary((id \ + 2559)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2568)(content(Whitespace\" \"))))(Secondary((id \ + 2564)(content(Whitespace\" \"))))(Secondary((id \ + 2565)(content(Whitespace\" \"))))(Secondary((id \ + 2566)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2570)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2575)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2576)(content(Whitespace\" \"))))(Tile((id \ + 2602)(label(has_at_least_two_elements))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2603)(content(Whitespace\" \"))))(Tile((id \ + 2604)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2606)(content(Whitespace\" \"))))(Tile((id 2607)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2610)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2611)(content(Whitespace\" \"))))(Tile((id \ + 2614)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2615)(content(Whitespace\" \"))))(Tile((id \ + 2619)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2620)(content(Whitespace\" \")))))((Secondary((id \ + 2623)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2627)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 2628)(content(Whitespace\" \"))))(Tile((id \ + 2631)(label(xs))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2632)(content(Whitespace\" \")))))))))(Secondary((id \ + 2636)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2641)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2642)(content(Whitespace\" \ + \"))))(Tile((id 2645)(label(xs))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2646)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2647)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2649)(content(Whitespace\" \ + \"))))(Tile((id 2652)(label([]))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2653)(content(Whitespace\" \")))))))))(Secondary((id \ + 2656)(content(Whitespace\" \"))))(Tile((id \ + 2661)(label(false))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2662)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2663)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2665)(content(Whitespace\" \ + \"))))(Tile((id 2667)(label(hd))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 2670)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 6))(sort Pat))((shape(Concave 6))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2673)(label([]))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2674)(content(Whitespace\" \")))))))))(Secondary((id \ + 2677)(content(Whitespace\" \"))))(Tile((id \ + 2682)(label(false))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2683)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2684)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2686)(content(Whitespace\" \ + \"))))(Tile((id 2687)(label(a))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 2690)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 6))(sort Pat))((shape(Concave 6))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2691)(label(b))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2694)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 6))(sort Pat))((shape(Concave 6))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2697)(label([]))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2698)(content(Whitespace\" \")))))))))(Secondary((id \ + 2701)(content(Whitespace\" \"))))(Tile((id \ + 2705)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2710)(content(Whitespace\" \"))))(Secondary((id \ + 2706)(content(Whitespace\" \"))))(Secondary((id \ + 2707)(content(Whitespace\" \"))))(Secondary((id \ + 2708)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2717)(content(Whitespace\" \"))))(Secondary((id \ + 2713)(content(Whitespace\" \"))))(Secondary((id \ + 2714)(content(Whitespace\" \"))))(Secondary((id \ + 2715)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2719)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3008)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3018)(content(Comment\"# Strings #\"))))(Secondary((id \ + 2722)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2726)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2727)(content(Whitespace\" \"))))(Tile((id \ + 2739)(label(string_lits))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2740)(content(Whitespace\" \")))))((Secondary((id \ + 2743)(content(Whitespace\" \"))))(Tile((id \ + 2757)(label(\"\\\"Hello, world!\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2760)(content(Whitespace\" \")))))))))(Secondary((id \ + 2762)(content(Whitespace\" \"))))(Secondary((id \ + 2764)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2768)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2769)(content(Whitespace\" \"))))(Tile((id \ + 2785)(label(string_equality))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2786)(content(Whitespace\" \")))))((Secondary((id \ + 2789)(content(Whitespace\" \"))))(Tile((id \ + 2800)(label(string_lits))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2801)(content(Whitespace\" \"))))(Tile((id \ + 2805)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2806)(content(Whitespace\" \"))))(Tile((id \ + 2820)(label(\"\\\"Hello, world!\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2823)(content(Whitespace\" \")))))))))(Secondary((id \ + 2825)(content(Whitespace\" \"))))(Secondary((id \ + 3019)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3409)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3466)(content(Comment\"# Non-empty holes are the red dotted \ + boxes around errors #\"))))(Secondary((id \ + 3467)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3519)(content(Comment\"# (you can still run programs with \ + non-empty holes) #\"))))(Secondary((id \ + 3520)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3524)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3525)(content(Whitespace\" \"))))(Tile((id \ + 3540)(label(non_empty_hole))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 3541)(content(Whitespace\" \"))))(Tile((id \ + 3542)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3544)(content(Whitespace\" \"))))(Tile((id \ + 3547)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3548)(content(Whitespace\" \")))))((Secondary((id \ + 3551)(content(Whitespace\" \"))))(Tile((id \ + 3555)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3558)(content(Whitespace\" \")))))))))(Secondary((id \ + 3560)(content(Whitespace\" \"))))(Secondary((id \ + 3562)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3563)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3564)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3565)(content(Whitespace\" \"))))(Tile((id \ + 3566)(label(+))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 5))(sort Exp))((shape(Concave 5))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3568)(content(Whitespace\" \"))))(Tile((id \ + 3569)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2827)(content(Whitespace\"\\226\\143\\142\")))))))))))(caret \ + Outer))"; + backup_text = + "# Hazel Language Quick Reference #\n\n\ + # Empty holes stand for missing expressions, patterns, or \ + types #\n\ + let empty_hole = in\n\n\ + # Integers #\n\ + let int_lits : Int = 1 in\n\ + let negation = -1 in\n\ + let arithmetic = 1*2 + 8/4 in\n\ + let int_comparison = (10 == 10, 1 < 2, 2 <= 3, 3 > 2, 2 >= \ + 1) in\n\n\ + # Floating Point Numbers #\n\ + let float_lits : Float = 1.5 in\n\ + let float_artih = 1. *. 2. +. 8. /. 4. in\n\ + let float_comparison = (10. ==. 10., 1. <. 2., 2. <=. 3., \ + 3. >. 2., 2. >=. 1.) in\n\n\ + # Booleans #\n\ + let booleans : (Bool, Bool) = (true, false) in\n\ + let conditionals =\n\ + let (x, y) = (2 + 2, 3 + 3) in\n\ + if y > x then 1 \n\ + else 2 \n\ + in\n\n\ + # Tuples #\n\ + let tuples : (Int, Bool, (Bool, Int)) = (1, true, (false, \ + 3)) in\n\ + let (a, b, (c, d)) = tuples in\n\n\ + # Functions #\n\ + let y : (Int, Int, Int) -> Int =\n\ + fun (m, x, b) -> m * x + b \n\ + in\n\n\ + # Recursive Functions (arrow type annotation required) #\n\ + let double_recursively : Int -> Int =\n\ + fun n ->\n\ + if n == 0 then 0 \n\ + else double_recursively(n - 1) + 2 \n\ + in\n\n\ + # Lists #\n\ + let empty_list : [Int] = [] in\n\ + let non_empty_list : [Int] = 1::2::3::[] in\n\ + let list_literals : [Int] = [1, 2, 3] in\n\ + let length : [Int] -> Int =\n\ + fun xs ->\n\ + case xs\n\ + | [] => 0\n\ + | hd::tl => 1 + length(tl) \n\ + end \n\ + in\n\ + let has_at_least_two_elements : [Int] -> Bool =\n\ + fun xs ->\n\ + case xs\n\ + | [] => false\n\ + | hd::[] => false\n\ + | a::b::[] => true \n\ + end \n\ + in\n\n\ + # Strings #\n\ + let string_lits = \"Hello, world!\" in \n\ + let string_equality = string_lits $== \"Hello, world!\" in \n\n\ + # Non-empty holes are the red dotted boxes around errors #\n\ + # (you can still run programs with non-empty holes) #\n\ + let non_empty_hole : Int = true in \n\n\ + 2 + 2\n"; + } ) ); + ( "Types & errors", + ( 25454, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(()((Secondary((id \ + 23732)(content(Comment\"#Types and type error \ + examples#\"))))(Secondary((id \ + 23733)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 23734)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23738)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25393)(content(Whitespace\" \"))))(Tile((id \ + 25396)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 23739)(content(Whitespace\" \")))))((Secondary((id \ + 23744)(content(Whitespace\" \"))))(Tile((id \ + 23751)(label(unbound))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23754)(content(Whitespace\" \")))))))))(Secondary((id \ + 23756)(content(Whitespace\" \"))))(Secondary((id \ + 23760)(content(Comment #err#))))(Secondary((id \ + 23761)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23765)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23766)(content(Whitespace\" \"))))(Tile((id \ + 23776)(label(Undefined))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 23777)(content(Whitespace\" \")))))((Secondary((id \ + 23779)(content(Whitespace\" \"))))(Tile((id \ + 23788)(label(Undefined))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23791)(content(Whitespace\" \")))))))))(Secondary((id \ + 23793)(content(Whitespace\" \"))))(Secondary((id \ + 23801)(content(Comment\"# 2x err#\"))))(Secondary((id \ + 23802)(content(Whitespace\" \"))))(Secondary((id \ + 23803)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23807)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23808)(content(Whitespace\" \"))))(Tile((id \ + 23813)(label(true))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 23814)(content(Whitespace\" \")))))((Secondary((id \ + 23816)(content(Whitespace\" \"))))(Tile((id \ + 23817)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23820)(content(Whitespace\" \")))))))))(Secondary((id \ + 23822)(content(Whitespace\" \"))))(Secondary((id \ + 23826)(content(Comment #err#))))(Secondary((id \ + 23827)(content(Whitespace\" \"))))(Secondary((id \ + 23828)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 23829)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23833)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25453)(content(Whitespace\" \"))))(Grout((id 23838)(shape \ + Convex)))(Secondary((id 23834)(content(Whitespace\" \ + \")))))((Secondary((id 23839)(content(Whitespace\" \ + \"))))(Tile((id 23842)(label(if then else))(mold((out \ + Exp)(in_(Exp Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 12))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 23843)(content(Whitespace\" \ + \"))))(Tile((id 23848)(label(true))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23851)(content(Whitespace\" \")))))((Secondary((id \ + 23855)(content(Whitespace\" \"))))(Tile((id \ + 23856)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23859)(content(Whitespace\" \")))))))))(Secondary((id \ + 23863)(content(Whitespace\" \"))))(Tile((id \ + 23865)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23868)(content(Whitespace\" \")))))))))(Secondary((id \ + 23870)(content(Whitespace\" \"))))(Secondary((id \ + 23874)(content(Comment #err#))))(Secondary((id \ + 23875)(content(Whitespace\" \"))))(Secondary((id \ + 23876)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23880)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23881)(content(Whitespace\" \"))))(Tile((id \ + 23883)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 23884)(content(Whitespace\" \")))))((Secondary((id \ + 23886)(content(Whitespace\" \"))))(Tile((id 23889)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23890)(content(Whitespace\" \"))))(Tile((id \ + 23895)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23898)(content(Whitespace\" \")))))((Secondary((id \ + 23902)(content(Whitespace\" \"))))(Tile((id \ + 23903)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23906)(content(Whitespace\" \")))))))))(Secondary((id \ + 23910)(content(Whitespace\" \"))))(Tile((id \ + 23912)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23915)(content(Whitespace\" \")))))))))(Secondary((id \ + 23917)(content(Whitespace\" \"))))(Secondary((id \ + 23921)(content(Comment #err#))))(Secondary((id \ + 23922)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23926)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23927)(content(Whitespace\" \"))))(Tile((id \ + 23929)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 23930)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25452)(content(Whitespace\" \"))))(Grout((id 23935)(shape \ + Convex)))(Secondary((id 23932)(content(Whitespace\" \ + \")))))((Secondary((id 23936)(content(Whitespace\" \ + \"))))(Tile((id 23939)(label(if then else))(mold((out \ + Exp)(in_(Exp Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 12))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id 23940)(content(Whitespace\" \ + \"))))(Tile((id 23945)(label(true))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23948)(content(Whitespace\" \")))))((Secondary((id \ + 23952)(content(Whitespace\" \"))))(Tile((id \ + 23953)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23956)(content(Whitespace\" \")))))))))(Secondary((id \ + 23960)(content(Whitespace\" \"))))(Tile((id \ + 23962)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23965)(content(Whitespace\" \")))))))))(Secondary((id \ + 23967)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 23971)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23972)(content(Whitespace\" \"))))(Tile((id \ + 23974)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 23975)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 23977)(content(Whitespace\" \"))))(Tile((id \ + 23980)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 23981)(content(Whitespace\" \")))))((Secondary((id \ + 23983)(content(Whitespace\" \"))))(Tile((id 23986)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 23987)(content(Whitespace\" \"))))(Tile((id \ + 23992)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 23995)(content(Whitespace\" \")))))((Secondary((id \ + 23999)(content(Whitespace\" \"))))(Tile((id \ + 24000)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24003)(content(Whitespace\" \")))))))))(Secondary((id \ + 24007)(content(Whitespace\" \"))))(Tile((id \ + 24009)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24012)(content(Whitespace\" \")))))))))(Secondary((id \ + 24014)(content(Whitespace\" \"))))(Secondary((id \ + 24018)(content(Comment #err#))))(Secondary((id \ + 24019)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24023)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24024)(content(Whitespace\" \"))))(Tile((id \ + 24026)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24027)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24029)(content(Whitespace\" \"))))(Tile((id \ + 24033)(label(Fake))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24034)(content(Whitespace\" \")))))((Secondary((id \ + 24036)(content(Whitespace\" \"))))(Tile((id 24039)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24040)(content(Whitespace\" \"))))(Tile((id \ + 24045)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24048)(content(Whitespace\" \")))))((Secondary((id \ + 24052)(content(Whitespace\" \"))))(Tile((id \ + 24053)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24056)(content(Whitespace\" \")))))))))(Secondary((id \ + 24060)(content(Whitespace\" \"))))(Tile((id \ + 24064)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24067)(content(Whitespace\" \")))))))))(Secondary((id \ + 24069)(content(Whitespace\" \"))))(Secondary((id \ + 24073)(content(Comment #err#))))(Secondary((id \ + 24074)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24078)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24079)(content(Whitespace\" \"))))(Tile((id \ + 24081)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24082)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24084)(content(Whitespace\" \"))))(Tile((id \ + 24085)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24086)(content(Whitespace\" \")))))((Secondary((id \ + 24088)(content(Whitespace\" \"))))(Tile((id 24091)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24092)(content(Whitespace\" \"))))(Tile((id \ + 24097)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24100)(content(Whitespace\" \")))))((Secondary((id \ + 24104)(content(Whitespace\" \"))))(Tile((id \ + 24105)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24108)(content(Whitespace\" \")))))))))(Secondary((id \ + 24112)(content(Whitespace\" \"))))(Tile((id \ + 24114)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24117)(content(Whitespace\" \")))))))))(Secondary((id \ + 24119)(content(Whitespace\" \"))))(Secondary((id \ + 24126)(content(Comment\"#2x err#\"))))(Secondary((id \ + 24127)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24131)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24132)(content(Whitespace\" \"))))(Tile((id \ + 24134)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24135)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24137)(content(Whitespace\" \"))))(Tile((id \ + 24138)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24139)(content(Whitespace\" \")))))((Secondary((id \ + 24141)(content(Whitespace\" \"))))(Tile((id \ + 24142)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24145)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24146)(content(Whitespace\" \"))))(Tile((id \ + 24151)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24154)(content(Whitespace\" \")))))((Secondary((id \ + 24158)(content(Whitespace\" \"))))(Tile((id \ + 24159)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24162)(content(Whitespace\" \")))))))))(Secondary((id \ + 24166)(content(Whitespace\" \"))))(Tile((id \ + 24168)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24169)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Grout((id 24175)(shape \ + Convex)))(Secondary((id 24171)(content(Whitespace\" \ + \"))))(Secondary((id 24172)(content(Whitespace\" \ + \"))))(Secondary((id 24173)(content(Whitespace\" \ + \")))))))))(Secondary((id 24177)(content(Whitespace\" \ + \"))))(Secondary((id 24181)(content(Comment \ + #err#))))(Secondary((id \ + 24182)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24186)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24187)(content(Whitespace\" \"))))(Tile((id \ + 24189)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24190)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24192)(content(Whitespace\" \"))))(Grout((id 24194)(shape \ + Convex)))(Tile((id 24193)(label(,))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 14))(sort \ + Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24195)(content(Whitespace\" \"))))(Tile((id \ + 24196)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24197)(content(Whitespace\" \")))))((Secondary((id \ + 24199)(content(Whitespace\" \"))))(Tile((id \ + 24200)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24203)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24204)(content(Whitespace\" \"))))(Tile((id \ + 24209)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24212)(content(Whitespace\" \")))))((Secondary((id \ + 24216)(content(Whitespace\" \"))))(Tile((id \ + 24217)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24220)(content(Whitespace\" \")))))))))(Secondary((id \ + 24224)(content(Whitespace\" \"))))(Tile((id \ + 24226)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24227)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Grout((id 24233)(shape \ + Convex)))(Secondary((id 24229)(content(Whitespace\" \ + \"))))(Secondary((id 24230)(content(Whitespace\" \ + \"))))(Secondary((id 24231)(content(Whitespace\" \ + \")))))))))(Secondary((id 24235)(content(Whitespace\" \ + \"))))(Secondary((id \ + 24236)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24240)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24241)(content(Whitespace\" \"))))(Tile((id 24243)(label([ \ + ]))(mold((out Pat)(in_(Pat))(nibs(((shape Convex)(sort \ + Pat))((shape Convex)(sort Pat))))))(shards(0 \ + 1))(children(((Tile((id 24244)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 24245)(content(Whitespace\" \")))))((Secondary((id \ + 24247)(content(Whitespace\" \"))))(Tile((id 24248)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 24249)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24252)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24253)(content(Whitespace\" \"))))(Tile((id \ + 24258)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24261)(content(Whitespace\" \")))))((Secondary((id \ + 24265)(content(Whitespace\" \"))))(Tile((id \ + 24266)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24269)(content(Whitespace\" \")))))))))(Secondary((id \ + 24273)(content(Whitespace\" \"))))(Tile((id \ + 24275)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 24278)(content(Whitespace\" \")))))))))(Secondary((id \ + 24280)(content(Whitespace\" \"))))(Secondary((id \ + 24281)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24285)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24286)(content(Whitespace\" \"))))(Tile((id 24288)(label([ \ + ]))(mold((out Pat)(in_(Pat))(nibs(((shape Convex)(sort \ + Pat))((shape Convex)(sort Pat))))))(shards(0 \ + 1))(children(((Tile((id 24289)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 24290)(content(Whitespace\" \")))))((Secondary((id \ + 24292)(content(Whitespace\" \"))))(Tile((id \ + 24293)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24296)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24297)(content(Whitespace\" \"))))(Tile((id \ + 24302)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24305)(content(Whitespace\" \")))))((Secondary((id \ + 24309)(content(Whitespace\" \"))))(Tile((id \ + 24310)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24313)(content(Whitespace\" \")))))))))(Secondary((id \ + 24317)(content(Whitespace\" \"))))(Tile((id \ + 24319)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 24322)(content(Whitespace\" \")))))))))(Secondary((id \ + 24324)(content(Whitespace\" \"))))(Secondary((id \ + 24331)(content(Comment\"#2x err#\"))))(Secondary((id \ + 24332)(content(Whitespace\" \"))))(Secondary((id \ + 24333)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 24334)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25411)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Grout((id \ + 25413)(shape Convex)))(Secondary((id \ + 25412)(content(Whitespace\" \")))))))))(Tile((id \ + 24338)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24342)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24343)(content(Whitespace\" \"))))(Tile((id \ + 24348)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24351)(content(Whitespace\" \")))))((Secondary((id \ + 24355)(content(Whitespace\" \"))))(Tile((id \ + 24356)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24359)(content(Whitespace\" \")))))))))(Secondary((id \ + 24363)(content(Whitespace\" \"))))(Tile((id \ + 24365)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24366)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24368)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24369)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 24370)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24374)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24375)(content(Whitespace\" \"))))(Tile((id \ + 24380)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24383)(content(Whitespace\" \")))))((Secondary((id \ + 24387)(content(Whitespace\" \"))))(Tile((id \ + 24388)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24391)(content(Whitespace\" \")))))))))(Secondary((id \ + 24395)(content(Whitespace\" \"))))(Tile((id \ + 24397)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24398)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24400)(content(Whitespace\" \"))))(Secondary((id \ + 24404)(content(Comment #err#))))(Secondary((id \ + 24405)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24406)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24407)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24408)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24412)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24413)(content(Whitespace\" \"))))(Tile((id \ + 24418)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24421)(content(Whitespace\" \")))))((Secondary((id \ + 24425)(content(Whitespace\" \"))))(Tile((id \ + 24426)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24429)(content(Whitespace\" \")))))))))(Secondary((id \ + 24433)(content(Whitespace\" \"))))(Tile((id \ + 24435)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24436)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24438)(content(Whitespace\" \"))))(Secondary((id \ + 24442)(content(Comment #err#))))(Secondary((id \ + 24443)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24444)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24448)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 25439)(content(Whitespace\" \"))))(Grout((id 25440)(shape \ + Convex)))(Secondary((id 25441)(content(Whitespace\" \ + \")))))))))(Secondary((id 25442)(content(Whitespace\" \ + \"))))(Grout((id 24457)(shape Convex))))))))(Tile((id \ + 24458)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24462)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24463)(content(Whitespace\" \"))))(Tile((id \ + 24468)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24471)(content(Whitespace\" \")))))((Secondary((id \ + 24475)(content(Whitespace\" \"))))(Tile((id \ + 24476)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24479)(content(Whitespace\" \")))))))))(Secondary((id \ + 24483)(content(Whitespace\" \"))))(Tile((id \ + 24485)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24486)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24488)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24489)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24493)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 24494)(content(Whitespace\" \"))))(Tile((id \ + 24496)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24497)(content(Whitespace\" \")))))))))(Secondary((id \ + 25443)(content(Whitespace\" \"))))(Grout((id 24502)(shape \ + Convex))))))))(Tile((id 24503)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24507)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24508)(content(Whitespace\" \"))))(Tile((id \ + 24513)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24516)(content(Whitespace\" \")))))((Secondary((id \ + 24520)(content(Whitespace\" \"))))(Tile((id \ + 24521)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24524)(content(Whitespace\" \")))))))))(Secondary((id \ + 24528)(content(Whitespace\" \"))))(Tile((id \ + 24530)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24531)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24533)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24534)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24538)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 24539)(content(Whitespace\" \"))))(Tile((id \ + 24541)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24542)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25444)(content(Whitespace\" \"))))(Grout((id 24548)(shape \ + Convex)))(Secondary((id 24544)(content(Whitespace\" \ + \")))))))))(Secondary((id 25445)(content(Whitespace\" \ + \"))))(Grout((id 24551)(shape Convex))))))))(Tile((id \ + 24552)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24556)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24557)(content(Whitespace\" \"))))(Tile((id \ + 24562)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24565)(content(Whitespace\" \")))))((Secondary((id \ + 24569)(content(Whitespace\" \"))))(Tile((id \ + 24570)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24573)(content(Whitespace\" \")))))))))(Secondary((id \ + 24577)(content(Whitespace\" \"))))(Tile((id \ + 24579)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24580)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24582)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24583)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24587)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 24588)(content(Whitespace\" \"))))(Tile((id \ + 24590)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24591)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24593)(content(Whitespace\" \"))))(Tile((id \ + 24596)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24597)(content(Whitespace\" \")))))))))(Secondary((id \ + 25446)(content(Whitespace\" \"))))(Grout((id 24602)(shape \ + Convex))))))))(Tile((id 24603)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24607)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24608)(content(Whitespace\" \"))))(Tile((id \ + 24613)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24616)(content(Whitespace\" \")))))((Secondary((id \ + 24620)(content(Whitespace\" \"))))(Tile((id \ + 24621)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24624)(content(Whitespace\" \")))))))))(Secondary((id \ + 24628)(content(Whitespace\" \"))))(Tile((id \ + 24630)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 24631)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24633)(content(Whitespace\" \"))))(Secondary((id \ + 24637)(content(Comment #err#))))(Secondary((id \ + 24638)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 24639)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24643)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24644)(content(Whitespace\" \"))))(Tile((id \ + 24646)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24647)(content(Whitespace\" \")))))((Secondary((id \ + 24649)(content(Whitespace\" \"))))(Tile((id \ + 24653)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 24654)(content(Whitespace\" \"))))(Tile((id \ + 24656)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24657)(content(Whitespace\" \")))))))))(Secondary((id \ + 24660)(content(Whitespace\" \"))))(Tile((id 24663)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24664)(content(Whitespace\" \"))))(Tile((id \ + 24669)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24672)(content(Whitespace\" \")))))((Secondary((id \ + 24676)(content(Whitespace\" \"))))(Tile((id \ + 24677)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24680)(content(Whitespace\" \")))))))))(Secondary((id \ + 24684)(content(Whitespace\" \"))))(Tile((id \ + 24686)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24689)(content(Whitespace\" \")))))))))(Secondary((id \ + 24691)(content(Whitespace\" \"))))(Secondary((id \ + 24695)(content(Comment #err#))))(Secondary((id \ + 24696)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24700)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24701)(content(Whitespace\" \"))))(Tile((id \ + 24703)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24704)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25417)(content(Whitespace\" \"))))(Grout((id 24709)(shape \ + Convex)))(Secondary((id 24706)(content(Whitespace\" \ + \")))))((Secondary((id 24710)(content(Whitespace\" \ + \"))))(Tile((id 24714)(label(fun ->))(mold((out \ + Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 24715)(content(Whitespace\" \ + \"))))(Tile((id 24717)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24718)(content(Whitespace\" \")))))))))(Secondary((id \ + 24721)(content(Whitespace\" \"))))(Tile((id 24724)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24725)(content(Whitespace\" \"))))(Tile((id \ + 24730)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24733)(content(Whitespace\" \")))))((Secondary((id \ + 24737)(content(Whitespace\" \"))))(Tile((id \ + 24738)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24741)(content(Whitespace\" \")))))))))(Secondary((id \ + 24745)(content(Whitespace\" \"))))(Tile((id \ + 24747)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24750)(content(Whitespace\" \")))))))))(Secondary((id \ + 24752)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24756)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24757)(content(Whitespace\" \"))))(Tile((id \ + 24759)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24760)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25416)(content(Whitespace\" \"))))(Grout((id 25415)(shape \ + Convex)))(Secondary((id 25419)(content(Whitespace\" \ + \"))))(Tile((id 24766)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25418)(content(Whitespace\" \"))))(Grout((id 24771)(shape \ + Convex)))(Secondary((id 24768)(content(Whitespace\" \ + \")))))((Secondary((id 24772)(content(Whitespace\" \ + \"))))(Tile((id 24776)(label(fun ->))(mold((out \ + Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 24777)(content(Whitespace\" \ + \"))))(Tile((id 24779)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24780)(content(Whitespace\" \")))))))))(Secondary((id \ + 24783)(content(Whitespace\" \"))))(Tile((id 24786)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24787)(content(Whitespace\" \"))))(Tile((id \ + 24792)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24795)(content(Whitespace\" \")))))((Secondary((id \ + 24799)(content(Whitespace\" \"))))(Tile((id \ + 24800)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24803)(content(Whitespace\" \")))))))))(Secondary((id \ + 24807)(content(Whitespace\" \"))))(Tile((id \ + 24809)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24812)(content(Whitespace\" \")))))))))(Secondary((id \ + 24814)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24818)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24819)(content(Whitespace\" \"))))(Tile((id \ + 24821)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24822)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24824)(content(Whitespace\" \"))))(Grout((id 24829)(shape \ + Convex)))(Secondary((id 25420)(content(Whitespace\" \ + \"))))(Tile((id 24828)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24830)(content(Whitespace\" \"))))(Tile((id \ + 24833)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24834)(content(Whitespace\" \")))))((Secondary((id \ + 24836)(content(Whitespace\" \"))))(Tile((id \ + 24840)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 13))(sort \ + Exp))))))(shards(0 1))(children(((Secondary((id \ + 24841)(content(Whitespace\" \"))))(Tile((id \ + 24843)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24844)(content(Whitespace\" \")))))))))(Secondary((id \ + 24847)(content(Whitespace\" \"))))(Tile((id 24850)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24851)(content(Whitespace\" \"))))(Tile((id \ + 24856)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24859)(content(Whitespace\" \")))))((Secondary((id \ + 24863)(content(Whitespace\" \"))))(Tile((id \ + 24864)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24867)(content(Whitespace\" \")))))))))(Secondary((id \ + 24871)(content(Whitespace\" \"))))(Tile((id \ + 24873)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24876)(content(Whitespace\" \")))))))))(Secondary((id \ + 24878)(content(Whitespace\" \"))))(Secondary((id \ + 24882)(content(Comment #err#))))(Secondary((id \ + 24883)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24887)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24888)(content(Whitespace\" \"))))(Tile((id \ + 24890)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 24891)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24893)(content(Whitespace\" \"))))(Grout((id 24898)(shape \ + Convex)))(Secondary((id 25421)(content(Whitespace\" \ + \"))))(Tile((id 24897)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 24899)(content(Whitespace\" \"))))(Tile((id 25423)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Grout((id 25431)(shape \ + Convex))))))))(Secondary((id 24903)(content(Whitespace\" \ + \")))))((Secondary((id 24905)(content(Whitespace\" \ + \"))))(Tile((id 24909)(label(fun ->))(mold((out \ + Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 24910)(content(Whitespace\" \ + \"))))(Tile((id 24912)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 24913)(content(Whitespace\" \")))))))))(Secondary((id \ + 24916)(content(Whitespace\" \"))))(Tile((id 24919)(label(if \ + then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ + Convex)(sort Exp))((shape(Concave 12))(sort \ + Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24920)(content(Whitespace\" \"))))(Tile((id \ + 24925)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24928)(content(Whitespace\" \")))))((Secondary((id \ + 24932)(content(Whitespace\" \"))))(Tile((id \ + 24933)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24936)(content(Whitespace\" \")))))))))(Secondary((id \ + 24940)(content(Whitespace\" \"))))(Tile((id \ + 24942)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24945)(content(Whitespace\" \")))))))))(Secondary((id \ + 24947)(content(Whitespace\" \"))))(Secondary((id \ + 24954)(content(Comment\"#2x err#\"))))(Secondary((id \ + 24955)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 24956)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25448)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Grout((id \ + 25449)(shape Convex))))))))(Tile((id \ + 24962)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 24963)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 24964)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 24967)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 24968)(content(Whitespace\" \"))))(Tile((id \ + 24973)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24976)(content(Whitespace\" \")))))((Secondary((id \ + 24980)(content(Whitespace\" \"))))(Tile((id \ + 24981)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24984)(content(Whitespace\" \")))))))))(Secondary((id \ + 24988)(content(Whitespace\" \"))))(Tile((id \ + 24990)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Tile((id \ + 24991)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 24993)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 24994)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 24997)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 24998)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 24999)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 25002)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25003)(content(Whitespace\" \"))))(Tile((id \ + 25008)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25011)(content(Whitespace\" \")))))((Secondary((id \ + 25015)(content(Whitespace\" \"))))(Tile((id \ + 25016)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25019)(content(Whitespace\" \")))))))))(Secondary((id \ + 25023)(content(Whitespace\" \"))))(Tile((id \ + 25025)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Tile((id \ + 25026)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25028)(content(Whitespace\" \"))))(Secondary((id \ + 25032)(content(Comment #err#))))(Secondary((id \ + 25033)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25034)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 25035)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25036)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25451)(content(Whitespace\" \"))))(Tile((id \ + 25038)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 25041)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 25042)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25043)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 25046)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25047)(content(Whitespace\" \"))))(Tile((id \ + 25052)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25055)(content(Whitespace\" \")))))((Secondary((id \ + 25059)(content(Whitespace\" \"))))(Tile((id \ + 25060)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25063)(content(Whitespace\" \")))))))))(Secondary((id \ + 25067)(content(Whitespace\" \"))))(Tile((id \ + 25069)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Tile((id \ + 25070)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25072)(content(Whitespace\" \"))))(Secondary((id \ + 25079)(content(Comment\"#2x err#\"))))(Secondary((id \ + 25080)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 25081)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25085)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Grout((id \ + 25090)(shape Convex)))(Secondary((id \ + 25086)(content(Whitespace\" \"))))(Secondary((id \ + 25088)(content(Whitespace\" \"))))(Secondary((id \ + 25089)(content(Whitespace\" \")))))((Secondary((id \ + 25091)(content(Whitespace\" \"))))(Tile((id 25092)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25093)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 25094)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25096)(content(Whitespace\" \"))))(Tile((id \ + 25098)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25099)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25101)(content(Whitespace\" \"))))(Tile((id \ + 25105)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25108)(content(Whitespace\" \")))))))))(Secondary((id \ + 25110)(content(Whitespace\" \"))))(Secondary((id \ + 25128)(content(Comment\"#err: \ + inconsistent#\"))))(Secondary((id \ + 25129)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25133)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25134)(content(Whitespace\" \"))))(Tile((id \ + 25136)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 25137)(content(Whitespace\" \")))))((Secondary((id \ + 25139)(content(Whitespace\" \"))))(Tile((id 25140)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25141)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 25142)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25144)(content(Whitespace\" \"))))(Tile((id \ + 25146)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25147)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25149)(content(Whitespace\" \"))))(Tile((id \ + 25153)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25156)(content(Whitespace\" \")))))))))(Secondary((id \ + 25158)(content(Whitespace\" \"))))(Secondary((id \ + 25176)(content(Comment\"#err: \ + inconsistent#\"))))(Secondary((id \ + 25177)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25181)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25182)(content(Whitespace\" \"))))(Tile((id \ + 25184)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25185)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25433)(content(Whitespace\" \"))))(Grout((id 25189)(shape \ + Convex)))(Secondary((id 25187)(content(Whitespace\" \ + \"))))(Secondary((id 25188)(content(Whitespace\" \ + \")))))((Secondary((id 25190)(content(Whitespace\" \ + \"))))(Tile((id 25191)(label([ ]))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 25192)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25193)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25195)(content(Whitespace\" \"))))(Tile((id \ + 25197)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25198)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25200)(content(Whitespace\" \"))))(Tile((id \ + 25204)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25207)(content(Whitespace\" \")))))))))(Secondary((id \ + 25209)(content(Whitespace\" \"))))(Secondary((id \ + 25210)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25214)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25215)(content(Whitespace\" \"))))(Tile((id \ + 25217)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25218)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25434)(content(Whitespace\" \"))))(Tile((id 25437)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Grout((id 25436)(shape \ + Convex))))))))(Secondary((id 25223)(content(Whitespace\" \ + \")))))((Secondary((id 25225)(content(Whitespace\" \ + \"))))(Tile((id 25226)(label([ ]))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 25227)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25228)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25230)(content(Whitespace\" \"))))(Tile((id \ + 25232)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25233)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25235)(content(Whitespace\" \"))))(Tile((id \ + 25239)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25242)(content(Whitespace\" \")))))))))(Secondary((id \ + 25244)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25248)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25249)(content(Whitespace\" \"))))(Tile((id \ + 25251)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25252)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25435)(content(Whitespace\" \"))))(Tile((id 25254)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 25257)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 25258)(content(Whitespace\" \")))))((Secondary((id \ + 25260)(content(Whitespace\" \"))))(Tile((id 25261)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25262)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 25263)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25265)(content(Whitespace\" \"))))(Tile((id \ + 25267)(label(1.))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25268)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 25270)(content(Whitespace\" \"))))(Tile((id \ + 25274)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25277)(content(Whitespace\" \")))))))))(Secondary((id \ + 25279)(content(Whitespace\" \"))))(Secondary((id \ + 25286)(content(Comment\"#2x err#\"))))(Secondary((id \ + 25287)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 25288)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25292)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25293)(content(Whitespace\" \"))))(Tile((id \ + 25295)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25296)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25298)(content(Whitespace\" \"))))(Tile((id 25299)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 25302)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 25303)(content(Whitespace\" \")))))((Secondary((id \ + 25305)(content(Whitespace\" \"))))(Tile((id \ + 25306)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25309)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 25310)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25311)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25314)(content(Whitespace\" \")))))))))(Secondary((id \ + 25316)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25320)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25321)(content(Whitespace\" \"))))(Tile((id \ + 25323)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25324)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25326)(content(Whitespace\" \"))))(Tile((id 25327)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 25330)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 25331)(content(Whitespace\" \")))))((Secondary((id \ + 25333)(content(Whitespace\" \"))))(Tile((id \ + 25336)(label(1.0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25339)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 25340)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25341)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25344)(content(Whitespace\" \")))))))))(Secondary((id \ + 25346)(content(Whitespace\" \"))))(Secondary((id \ + 25350)(content(Comment #err#))))(Secondary((id \ + 25351)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25355)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 25356)(content(Whitespace\" \"))))(Tile((id \ + 25358)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 25359)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25361)(content(Whitespace\" \"))))(Tile((id 25362)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 25365)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 25366)(content(Whitespace\" \")))))((Secondary((id \ + 25368)(content(Whitespace\" \"))))(Tile((id \ + 25369)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 25372)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Tile((id 25373)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 25376)(label(2.0))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 25379)(content(Whitespace\" \")))))))))(Secondary((id \ + 25381)(content(Whitespace\" \"))))(Secondary((id \ + 25385)(content(Comment #err#))))(Secondary((id \ + 25386)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 25390)(label(\"\\\"BYE\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))(ancestors())))(caret \ + Outer))"; + backup_text = + "#Types and type error examples#\n\n\ + let _ = unbound in #err#\n\ + let Undefined = Undefined in # 2x err# \n\ + let true = 2 in #err# \n\n\ + let = if true then 1 else 1. in #err# \n\ + let _ = if true then 1 else 1. in #err#\n\ + let _: = if true then 1 else 1. in\n\ + let _: Int = if true then 1 else 1. in #err#\n\ + let _: Fake = if true then 1 else true in #err#\n\ + let _, _ = if true then 1 else 1. in #2x err#\n\ + let _, _ = (if true then 1 else 1.), in #err#\n\ + let _: , _ = (if true then 1 else 1.), in \n\ + let [_] = [(if true then 1 else 1.)] in \n\ + let [_] = (if true then 1 else 1.) in #2x err# \n\n\ + ( )(if true then 1 else 1.);\n\ + 1(if true then 1 else 1.); #err#\n\ + (1)(if true then 1 else 1.); #err#\n\ + (fun -> )(if true then 1 else 1.);\n\ + (fun _ -> )(if true then 1 else 1.);\n\ + (fun _: -> )(if true then 1 else 1.);\n\ + (fun _: Int -> )(if true then 1 else 1.); #err#\n\n\ + let _ = fun x -> if true then 1 else 1. in #err#\n\ + let _: = fun x -> if true then 1 else 1. in\n\ + let _: -> = fun x -> if true then 1 else 1. in\n\ + let _: -> Int = fun x -> if true then 1 else 1. in #err#\n\ + let _: -> [ ] = fun x -> if true then 1 else 1. in #2x \ + err#\n\n\ + ( )::[(if true then 1 else 1.)];\n\ + 1::[(if true then 1 else 1.)]; #err#\n\ + (1, 1)::[(if true then 1 else 1.)]; #2x err#\n\n\ + let = [1, 1., true] in #err: inconsistent#\n\ + let _ = [1, 1., true] in #err: inconsistent#\n\ + let _: = [1, 1., true] in \n\ + let _: [ ] = [1, 1., true] in\n\ + let _: [Int] = [1, 1., true] in #2x err#\n\n\ + let _: [Int] = 1::[2] in\n\ + let _: [Int] = 1.0::[2] in #err#\n\ + let _: [Int] = 1::[2.0] in #err#\n\ + \"BYE\""; + } ) ); + ( "ADT Statics", + ( 29384, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(()((Secondary((id \ + 8111)(content(Comment\"#Non-recursive sum/alias \ + tests#\"))))(Secondary((id \ + 8112)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8174)(content(Comment\"#all lines with trailing err comment \ + should have 1 error#\"))))(Secondary((id \ + 8175)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8209)(content(Comment\"#no other lines should have \ + errors#\"))))(Secondary((id \ + 6602)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6603)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6930)(content(Comment\"#type definitions: no \ + errors#\"))))(Secondary((id \ + 3939)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2974)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2975)(content(Whitespace\" \"))))(Grout((id 2979)(shape \ + Convex)))(Secondary((id 3016)(content(Whitespace\" \ + \")))))((Secondary((id 2980)(content(Whitespace\" \ + \"))))(Grout((id 8391)(shape Convex)))(Secondary((id \ + 2987)(content(Whitespace\" \")))))))))(Secondary((id \ + 3017)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3023)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3024)(content(Whitespace\" \"))))(Tile((id \ + 3054)(label(SingleNull))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 3039)(content(Whitespace\" \")))))((Secondary((id \ + 3041)(content(Whitespace\" \"))))(Tile((id \ + 3042)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3048)(label(One))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3049)(content(Whitespace\" \")))))))))(Secondary((id \ + 2861)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2867)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2868)(content(Whitespace\" \"))))(Tile((id \ + 3059)(label(Single))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2871)(content(Whitespace\" \")))))((Secondary((id \ + 2873)(content(Whitespace\" \"))))(Tile((id \ + 2874)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2876)(label(F))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 2878)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2942)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2883)(content(Whitespace\" \")))))))))(Secondary((id \ + 2885)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2046)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2047)(content(Whitespace\" \"))))(Tile((id \ + 3185)(label(GoodSum))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2050)(content(Whitespace\" \")))))((Secondary((id \ + 2052)(content(Whitespace\" \"))))(Tile((id \ + 2065)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2080)(content(Whitespace\" \"))))(Tile((id \ + 2068)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2069)(content(Whitespace\" \"))))(Tile((id \ + 2070)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2072)(content(Whitespace\" \"))))(Tile((id \ + 2073)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2074)(content(Whitespace\" \"))))(Tile((id \ + 2375)(label(C))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3186)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3201)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2077)(content(Whitespace\" \")))))))))(Secondary((id \ + 6117)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6123)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6124)(content(Whitespace\" \"))))(Tile((id \ + 6132)(label(Partial))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6133)(content(Whitespace\" \")))))((Secondary((id \ + 6135)(content(Whitespace\" \"))))(Tile((id \ + 6138)(label(Ok))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6139)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Grout((id \ + 6141)(shape Convex))))))))(Secondary((id \ + 6143)(content(Whitespace\" \"))))(Tile((id \ + 6172)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6181)(content(Whitespace\" \"))))(Grout((id 6180)(shape \ + Convex)))(Secondary((id 6173)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 3316)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2495)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2496)(content(Whitespace\" \"))))(Tile((id \ + 3477)(label(DoubleAlias))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2499)(content(Whitespace\" \")))))((Secondary((id \ + 2501)(content(Whitespace\" \"))))(Tile((id \ + 3460)(label(GoodSum))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2506)(content(Whitespace\" \")))))))))(Secondary((id \ + 1428)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1434)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1435)(content(Whitespace\" \"))))(Tile((id \ + 8239)(label(VerticalLeading))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1438)(content(Whitespace\" \")))))((Secondary((id \ + 8305)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 8307)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8308)(content(Whitespace\" \"))))(Tile((id \ + 8306)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1446)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1447)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1448)(content(Whitespace\" \"))))(Tile((id \ + 1449)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1451)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3631)(label(GoodSum))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 1456)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1457)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1458)(content(Whitespace\" \"))))(Tile((id \ + 1459)(label(C))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1461)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 1466)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1468)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1473)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 1476)(content(Whitespace\" \"))))(Secondary((id \ + 1474)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 3687)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3951)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6938)(content(Comment\"#incorrect or incomplete type \ + definitions#\"))))(Secondary((id \ + 3860)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3866)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3867)(content(Whitespace\" \"))))(Tile((id \ + 3879)(label(badTypeName))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3880)(content(Whitespace\" \")))))((Secondary((id \ + 3882)(content(Whitespace\" \"))))(Grout((id 7903)(shape \ + Convex)))(Secondary((id 3898)(content(Whitespace\" \ + \")))))))))(Secondary((id 6939)(content(Whitespace\" \ + \"))))(Secondary((id 7915)(content(Comment\"#err: invalid \ + type name#\"))))(Secondary((id \ + 3900)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3906)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3907)(content(Whitespace\" \"))))(Tile((id \ + 3908)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Grout((id \ + 3911)(shape Convex)))(Tile((id 3910)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4907)(content(Whitespace\" \"))))(Grout((id 3914)(shape \ + Convex))))))))(Secondary((id 3916)(content(Whitespace\" \ + \")))))((Secondary((id 3918)(content(Whitespace\" \ + \"))))(Grout((id 6260)(shape Convex)))(Secondary((id \ + 3936)(content(Whitespace\" \")))))))))(Secondary((id \ + 6974)(content(Whitespace\" \"))))(Secondary((id \ + 7938)(content(Comment\"#err: invalid type \ + name#\"))))(Secondary((id \ + 7939)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7945)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 7946)(content(Whitespace\" \"))))(Grout((id 7995)(shape \ + Convex)))(Secondary((id 7959)(content(Whitespace\" \ + \")))))((Secondary((id 7961)(content(Whitespace\" \ + \"))))(Tile((id 7974)(label(badTypeToken))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 7977)(content(Whitespace\" \")))))))))(Secondary((id \ + 7979)(content(Whitespace\" \"))))(Secondary((id \ + 8008)(content(Comment\"#err: invalid type \ + token#\"))))(Secondary((id \ + 6205)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6211)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6212)(content(Whitespace\" \"))))(Tile((id \ + 6253)(label(NotASum))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6221)(content(Whitespace\" \")))))((Secondary((id \ + 6223)(content(Whitespace\" \"))))(Tile((id \ + 6232)(label(NotInSum))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6233)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 6238)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 6241)(content(Whitespace\" \")))))))))(Secondary((id \ + 6995)(content(Whitespace\" \"))))(Secondary((id \ + 8363)(content(Comment\"#err: cons not in \ + sum#\"))))(Secondary((id \ + 8309)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 8315)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 8316)(content(Whitespace\" \"))))(Tile((id \ + 8371)(label(Bool))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 8321)(content(Whitespace\" \")))))((Secondary((id \ + 8330)(content(Whitespace\" \"))))(Grout((id 8329)(shape \ + Convex)))(Secondary((id 8323)(content(Whitespace\" \ + \"))))(Secondary((id 8324)(content(Whitespace\" \ + \")))))))))(Secondary((id 8328)(content(Whitespace\" \ + \"))))(Secondary((id 8361)(content(Comment\"#err: shadows \ + base type#\"))))(Secondary((id \ + 3688)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3694)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3695)(content(Whitespace\" \"))))(Tile((id \ + 3701)(label(Dupes))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 3702)(content(Whitespace\" \")))))((Secondary((id \ + 8009)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7772)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8012)(content(Whitespace\" \"))))(Tile((id \ + 3708)(label(Guy))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3709)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3714)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 8052)(content(Whitespace\" \"))))(Secondary((id \ + 8059)(content(Comment\"#no err#\"))))(Secondary((id \ + 8010)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3723)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3724)(content(Whitespace\" \"))))(Tile((id \ + 3728)(label(Guy))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3729)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3733)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 8033)(content(Whitespace\" \"))))(Secondary((id \ + 8051)(content(Comment\"#err: already \ + used#\"))))(Secondary((id \ + 8011)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6271)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6273)(content(Whitespace\" \"))))(Tile((id \ + 6276)(label(Guy))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6277)(content(Whitespace\" \")))))))))(Secondary((id \ + 7023)(content(Whitespace\" \"))))(Secondary((id \ + 8032)(content(Comment\"#err: already \ + used#\"))))(Secondary((id \ + 3800)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3807)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3808)(content(Whitespace\" \"))))(Tile((id \ + 3816)(label(BadCons))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 3817)(content(Whitespace\" \")))))((Secondary((id \ + 7701)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7770)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7771)(content(Whitespace\" \"))))(Tile((id \ + 7738)(label(Um))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 7739)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 7746)(label(Unbound))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 7747)(content(Whitespace\" \"))))(Secondary((id \ + 7769)(content(Comment\"#err: unbound type \ + var#\"))))(Secondary((id \ + 7524)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7532)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7533)(content(Whitespace\" \"))))(Tile((id \ + 7531)(label(invalid))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 7534)(content(Whitespace\" \"))))(Secondary((id \ + 7547)(content(Comment\"#err: invalid#\"))))(Secondary((id \ + 7517)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7522)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7523)(content(Whitespace\" \"))))(Tile((id \ + 7521)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7548)(content(Whitespace\" \"))))(Secondary((id \ + 7578)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 7498)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7497)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7501)(content(Whitespace\" \"))))(Tile((id \ + 3823)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3824)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3828)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 7602)(content(Whitespace\" \"))))(Secondary((id \ + 7632)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 7499)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3830)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3831)(content(Whitespace\" \"))))(Tile((id \ + 3832)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Grout((id \ + 3834)(shape Convex))))))))(Tile((id \ + 3836)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3840)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 7633)(content(Whitespace\" \"))))(Secondary((id \ + 7663)(content(Comment\"#err: expected cons found \ + type#\"))))(Secondary((id \ + 7500)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3842)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3843)(content(Whitespace\" \"))))(Tile((id \ + 3844)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3846)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 6020)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 3849)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3853)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 3856)(content(Whitespace\" \")))))))))(Secondary((id \ + 3859)(content(Whitespace\" \"))))(Secondary((id \ + 7700)(content(Comment\"#err: expected cons found \ + app#\"))))(Secondary((id \ + 1563)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3564)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8704)(content(Comment\"#sums in compound aliases dont add \ + ctrs to scope#\"))))(Secondary((id \ + 8930)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8985)(content(Comment\"#but compound alias types should \ + propagate analytically#\"))))(Secondary((id \ + 3512)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3518)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3519)(content(Whitespace\" \"))))(Tile((id \ + 9369)(label(CompoundAlias))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 3531)(content(Whitespace\" \")))))((Secondary((id \ + 3533)(content(Whitespace\" \"))))(Tile((id \ + 3534)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3538)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3539)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3540)(content(Whitespace\" \"))))(Tile((id \ + 3550)(label(Anonymous))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3551)(content(Whitespace\" \"))))(Tile((id \ + 3552)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3553)(content(Whitespace\" \"))))(Tile((id \ + 3557)(label(Sum))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 3560)(content(Whitespace\" \")))))))))(Secondary((id \ + 3562)(content(Whitespace\" \"))))(Secondary((id \ + 1485)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2243)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2244)(content(Whitespace\" \"))))(Tile((id \ + 9126)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2250)(content(Whitespace\" \")))))((Secondary((id \ + 2262)(content(Whitespace\" \"))))(Tile((id \ + 3503)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 8493)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3507)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 6011)(content(Whitespace\" \"))))(Tile((id \ + 3511)(label(Sum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2252)(content(Whitespace\" \")))))))))(Secondary((id \ + 6892)(content(Whitespace\" \"))))(Secondary((id \ + 7774)(content(Comment\"#err: not \ + defined#\"))))(Secondary((id \ + 8564)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 8569)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 8570)(content(Whitespace\" \"))))(Tile((id \ + 9128)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 8573)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9070)(content(Whitespace\" \"))))(Tile((id \ + 9383)(label(CompoundAlias))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8586)(content(Whitespace\" \")))))((Secondary((id \ + 8587)(content(Whitespace\" \"))))(Tile((id \ + 8588)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 8589)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 8591)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 8592)(content(Whitespace\" \"))))(Tile((id \ + 8596)(label(Sum))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 8599)(content(Whitespace\" \")))))))))(Secondary((id \ + 8987)(content(Whitespace\" \"))))(Secondary((id \ + 8996)(content(Comment\"#no error#\"))))(Secondary((id \ + 8805)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 8811)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 8812)(content(Whitespace\" \"))))(Tile((id \ + 9254)(label(Yorp))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 8818)(content(Whitespace\" \")))))((Secondary((id \ + 8819)(content(Whitespace\" \"))))(Tile((id \ + 8823)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8824)(content(Whitespace\" \"))))(Tile((id \ + 8826)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8827)(content(Whitespace\" \"))))(Tile((id \ + 8836)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 9229)(label(Inside))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8830)(content(Whitespace\" \"))))(Tile((id \ + 8831)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8832)(content(Whitespace\" \"))))(Tile((id \ + 9235)(label(Ouside))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 8835)(content(Whitespace\" \")))))))))(Secondary((id \ + 8837)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 8842)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 8843)(content(Whitespace\" \"))))(Tile((id \ + 9129)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 8847)(content(Whitespace\" \")))))((Secondary((id \ + 8853)(content(Whitespace\" \"))))(Tile((id 8858)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 8859)(content(Whitespace\" \ + \"))))(Tile((id 8860)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 8882)(content(Whitespace\" \")))))))))(Secondary((id \ + 8884)(content(Whitespace\" \"))))(Tile((id \ + 9241)(label(Inside))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 8889)(content(Whitespace\" \")))))))))(Secondary((id \ + 9032)(content(Whitespace\" \"))))(Secondary((id \ + 9049)(content(Comment\"#err: not \ + defined#\"))))(Secondary((id \ + 8494)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 9001)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 9002)(content(Whitespace\" \"))))(Tile((id \ + 9130)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 9006)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9071)(content(Whitespace\" \"))))(Tile((id \ + 9253)(label(Yorp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9010)(content(Whitespace\" \")))))((Secondary((id \ + 9011)(content(Whitespace\" \"))))(Tile((id 9016)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 9017)(content(Whitespace\" \ + \"))))(Tile((id 9018)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 9020)(content(Whitespace\" \")))))))))(Secondary((id \ + 9022)(content(Whitespace\" \"))))(Tile((id \ + 9248)(label(Inside))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 9029)(content(Whitespace\" \")))))))))(Secondary((id \ + 9051)(content(Whitespace\" \"))))(Secondary((id \ + 9060)(content(Comment\"#no error#\"))))(Secondary((id \ + 9073)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 9079)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 9080)(content(Whitespace\" \"))))(Tile((id \ + 9094)(label(Gargs))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 9095)(content(Whitespace\" \")))))((Secondary((id \ + 9096)(content(Whitespace\" \"))))(Tile((id 9097)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 9199)(label(BigGuy))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9102)(content(Whitespace\" \"))))(Tile((id \ + 9103)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9104)(content(Whitespace\" \"))))(Tile((id \ + 9211)(label(Small))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 9111)(content(Whitespace\" \")))))))))(Secondary((id \ + 9072)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 9116)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 9117)(content(Whitespace\" \"))))(Tile((id \ + 9131)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 9123)(content(Whitespace\" \")))))((Secondary((id \ + 9132)(content(Whitespace\" \"))))(Tile((id \ + 9206)(label(BigGuy))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 9137)(content(Whitespace\" \")))))))))(Secondary((id \ + 9178)(content(Whitespace\" \"))))(Secondary((id \ + 9195)(content(Comment\"#err: not \ + defined#\"))))(Secondary((id \ + 9138)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 9143)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 9144)(content(Whitespace\" \"))))(Tile((id \ + 9147)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 9149)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9150)(content(Whitespace\" \"))))(Tile((id \ + 9156)(label(Gargs))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9157)(content(Whitespace\" \")))))((Secondary((id \ + 9158)(content(Whitespace\" \"))))(Tile((id 9159)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 9217)(label(BigGuy))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 9166)(content(Whitespace\" \")))))))))(Secondary((id \ + 9167)(content(Whitespace\" \"))))(Secondary((id \ + 9176)(content(Comment\"#no error#\"))))(Secondary((id \ + 9255)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 9260)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 9261)(content(Whitespace\" \"))))(Tile((id \ + 9262)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 9264)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9265)(content(Whitespace\" \"))))(Tile((id \ + 9275)(label(Gargs))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9271)(content(Whitespace\" \")))))((Secondary((id \ + 9276)(content(Whitespace\" \"))))(Tile((id \ + 9283)(label(BigGuy))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 9284)(content(Whitespace\" \"))))(Tile((id \ + 9286)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 9287)(content(Whitespace\" \"))))(Tile((id 9338)(label([ \ + ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 9344)(label(BigGuy))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 9291)(content(Whitespace\" \")))))))))(Secondary((id \ + 9292)(content(Whitespace\" \"))))(Secondary((id \ + 9354)(content(Comment\"#no error#\"))))(Secondary((id \ + 9293)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4008)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8078)(content(Comment\"#unbound tyvars treated as \ + unknown-typehole#\"))))(Secondary((id \ + 4053)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4058)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4059)(content(Whitespace\" \"))))(Tile((id \ + 4060)(label(a))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 4062)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4066)(label(Bad))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4067)(content(Whitespace\" \")))))((Secondary((id \ + 4069)(content(Whitespace\" \"))))(Tile((id \ + 8085)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4075)(content(Whitespace\" \")))))))))(Secondary((id \ + 4077)(content(Whitespace\" \"))))(Tile((id \ + 4078)(label(a))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 8079)(content(Whitespace\" \"))))(Tile((id \ + 8082)(label(==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 8083)(content(Whitespace\" \"))))(Tile((id \ + 8086)(label(0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4080)(label(\";\"))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 10))(sort \ + Exp))((shape(Concave 10))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 6758)(content(Whitespace\" \"))))(Secondary((id \ + 7776)(content(Comment\"#err: not bound#\"))))(Secondary((id \ + 6021)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6022)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8093)(content(Comment\"#non-sum-types cant be \ + recursive#\"))))(Secondary((id \ + 6070)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6076)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6077)(content(Whitespace\" \"))))(Tile((id \ + 6081)(label(Lol))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6082)(content(Whitespace\" \")))))((Secondary((id \ + 6084)(content(Whitespace\" \"))))(Tile((id \ + 6088)(label(Lol))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6091)(content(Whitespace\" \")))))))))(Secondary((id \ + 6736)(content(Whitespace\" \"))))(Secondary((id \ + 7778)(content(Comment\"#err: not bound#\"))))(Secondary((id \ + 6466)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6703)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6805)(content(Comment\"#no errors: analytic \ + shadowing#\"))))(Secondary((id \ + 6806)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6812)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6813)(content(Whitespace\" \"))))(Tile((id \ + 6819)(label(Tork1))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6820)(content(Whitespace\" \")))))((Secondary((id \ + 6822)(content(Whitespace\" \"))))(Tile((id \ + 6823)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6829)(label(Blob))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6832)(content(Whitespace\" \")))))))))(Secondary((id \ + 6834)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6840)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6841)(content(Whitespace\" \"))))(Tile((id \ + 6847)(label(Tork2))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6848)(content(Whitespace\" \")))))((Secondary((id \ + 6850)(content(Whitespace\" \"))))(Tile((id \ + 6851)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6857)(label(Blob))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6860)(content(Whitespace\" \")))))))))(Secondary((id \ + 6862)(content(Whitespace\" \"))))(Secondary((id \ + 6863)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6868)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 6869)(content(Whitespace\" \"))))(Tile((id \ + 6870)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 6872)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6878)(label(Tork1))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6879)(content(Whitespace\" \")))))((Secondary((id \ + 6881)(content(Whitespace\" \"))))(Tile((id \ + 6886)(label(Blob))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 6889)(content(Whitespace\" \")))))))))(Secondary((id \ + 6467)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3994)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 5074)(content(Comment\"#exp tests: \ + happy#\"))))(Secondary((id \ + 4344)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4350)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4351)(content(Whitespace\" \"))))(Tile((id \ + 5397)(label(YoDawg))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 4354)(content(Whitespace\" \")))))((Secondary((id \ + 4356)(content(Whitespace\" \"))))(Secondary((id \ + 4357)(content(Whitespace\" \"))))(Tile((id \ + 4952)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4360)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4434)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 6501)(content(Whitespace\" \"))))(Tile((id \ + 6507)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 8413)(content(Whitespace\" \"))))(Tile((id \ + 6502)(label(Bo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 6503)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 6506)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 4367)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4368)(content(Whitespace\" \"))))(Tile((id \ + 4980)(label(Dawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4371)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4438)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 4378)(content(Whitespace\" \")))))))))(Secondary((id \ + 4388)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4393)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4394)(content(Whitespace\" \"))))(Tile((id \ + 4728)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4397)(content(Whitespace\" \")))))((Secondary((id \ + 4399)(content(Whitespace\" \"))))(Tile((id \ + 4954)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4402)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4403)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4407)(content(Whitespace\" \")))))))))(Secondary((id \ + 4595)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4600)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4601)(content(Whitespace\" \"))))(Tile((id \ + 4730)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5016)(content(Whitespace\" \"))))(Tile((id \ + 4604)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5013)(content(Whitespace\" \"))))(Tile((id \ + 6116)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4607)(content(Whitespace\" \")))))((Secondary((id \ + 4609)(content(Whitespace\" \"))))(Tile((id \ + 4956)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4612)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4613)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4617)(content(Whitespace\" \")))))))))(Secondary((id \ + 4619)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4624)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4625)(content(Whitespace\" \"))))(Tile((id \ + 4732)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5017)(content(Whitespace\" \"))))(Tile((id \ + 4628)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5012)(content(Whitespace\" \"))))(Tile((id \ + 4630)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5007)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4633)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4638)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 4639)(content(Whitespace\" \")))))((Secondary((id \ + 4641)(content(Whitespace\" \"))))(Tile((id \ + 5009)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4644)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4649)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4652)(content(Whitespace\" \")))))))))(Secondary((id \ + 4656)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4661)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4662)(content(Whitespace\" \"))))(Tile((id \ + 4734)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5018)(content(Whitespace\" \"))))(Tile((id \ + 4665)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5014)(content(Whitespace\" \"))))(Tile((id \ + 4667)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 5005)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5010)(content(Whitespace\" \"))))(Tile((id \ + 4670)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5011)(content(Whitespace\" \"))))(Tile((id \ + 4984)(label(Dawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4673)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4674)(content(Whitespace\" \"))))(Tile((id \ + 4678)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 4679)(content(Whitespace\" \")))))((Secondary((id \ + 4681)(content(Whitespace\" \"))))(Tile((id \ + 4682)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4989)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4685)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4686)(label(5))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4690)(content(Whitespace\" \")))))))))(Secondary((id \ + 4692)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4697)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4698)(content(Whitespace\" \"))))(Tile((id \ + 4736)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5019)(content(Whitespace\" \"))))(Tile((id \ + 4701)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5015)(content(Whitespace\" \"))))(Tile((id \ + 4713)(label(DoubleAlias))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4714)(content(Whitespace\" \")))))((Secondary((id \ + 4716)(content(Whitespace\" \"))))(Tile((id \ + 4717)(label(C))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4719)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4720)(label(4))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4724)(content(Whitespace\" \")))))))))(Secondary((id \ + 4782)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4474)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4851)(content(Comment\"#exp tests: \ + errors#\"))))(Secondary((id \ + 4783)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4788)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4789)(content(Whitespace\" \"))))(Tile((id \ + 4837)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4792)(content(Whitespace\" \")))))((Secondary((id \ + 4794)(content(Whitespace\" \"))))(Tile((id \ + 4795)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4797)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4798)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4802)(content(Whitespace\" \")))))))))(Secondary((id \ + 7107)(content(Whitespace\" \"))))(Secondary((id \ + 7780)(content(Comment\"#err: incons with \ + arrow#\"))))(Secondary((id \ + 4804)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4809)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4810)(content(Whitespace\" \"))))(Tile((id \ + 4835)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4813)(content(Whitespace\" \")))))((Secondary((id \ + 4815)(content(Whitespace\" \"))))(Tile((id \ + 4825)(label(Undefined))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4826)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4827)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4831)(content(Whitespace\" \")))))))))(Secondary((id \ + 7135)(content(Whitespace\" \"))))(Secondary((id \ + 7782)(content(Comment\"#err: cons \ + undefined#\"))))(Secondary((id \ + 4737)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4479)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4480)(content(Whitespace\" \"))))(Tile((id \ + 4739)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4483)(content(Whitespace\" \")))))((Secondary((id \ + 4485)(content(Whitespace\" \"))))(Tile((id \ + 4486)(label(B))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4488)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4493)(label(\"\\\"lol\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4496)(content(Whitespace\" \")))))))))(Secondary((id \ + 7158)(content(Whitespace\" \"))))(Secondary((id \ + 7794)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 4444)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4546)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4547)(content(Whitespace\" \"))))(Tile((id \ + 4741)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5020)(content(Whitespace\" \"))))(Tile((id \ + 4550)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4551)(content(Whitespace\" \"))))(Tile((id \ + 4552)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5000)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4555)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4560)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 4561)(content(Whitespace\" \")))))((Secondary((id \ + 4563)(content(Whitespace\" \"))))(Tile((id \ + 4958)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4574)(content(Whitespace\" \")))))))))(Secondary((id \ + 7183)(content(Whitespace\" \"))))(Secondary((id \ + 7793)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 4410)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1756)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1757)(content(Whitespace\" \"))))(Tile((id \ + 4743)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5021)(content(Whitespace\" \"))))(Tile((id \ + 1760)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1761)(content(Whitespace\" \"))))(Tile((id \ + 1762)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5003)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1765)(content(Whitespace\" \")))))((Secondary((id \ + 1767)(content(Whitespace\" \"))))(Tile((id \ + 4960)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1770)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4582)(label(\"\\\"lol\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1778)(content(Whitespace\" \")))))))))(Secondary((id \ + 1780)(content(Whitespace\" \"))))(Secondary((id \ + 7792)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 1713)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1718)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1719)(content(Whitespace\" \"))))(Tile((id \ + 4745)(label(_))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5022)(content(Whitespace\" \"))))(Tile((id \ + 1722)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1723)(content(Whitespace\" \"))))(Tile((id \ + 4590)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4593)(label(One))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1735)(content(Whitespace\" \")))))((Secondary((id \ + 1737)(content(Whitespace\" \"))))(Tile((id \ + 4962)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1740)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4594)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1748)(content(Whitespace\" \")))))))))(Secondary((id \ + 7220)(content(Whitespace\" \"))))(Secondary((id \ + 7791)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 5051)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 5052)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 7272)(content(Comment\"#pat tests: happy (but refutable \ + patterns so weird)#\"))))(Secondary((id \ + 5239)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5244)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5245)(content(Whitespace\" \"))))(Tile((id \ + 6526)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5249)(content(Whitespace\" \")))))((Secondary((id \ + 5251)(content(Whitespace\" \"))))(Tile((id \ + 6509)(label(Bo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5257)(content(Whitespace\" \")))))))))(Secondary((id \ + 5286)(content(Whitespace\" \"))))(Secondary((id \ + 5307)(content(Comment\"#kind of a weird \ + edge#\"))))(Secondary((id \ + 5075)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5080)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5081)(content(Whitespace\" \"))))(Tile((id \ + 5139)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5140)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5341)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 5084)(content(Whitespace\" \")))))((Secondary((id \ + 5154)(content(Whitespace\" \"))))(Tile((id \ + 5159)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5149)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5164)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5086)(content(Whitespace\" \")))))))))(Secondary((id \ + 5428)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5433)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5434)(content(Whitespace\" \"))))(Tile((id \ + 5437)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5438)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5757)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 5441)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5442)(content(Whitespace\" \"))))(Tile((id \ + 5449)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5450)(content(Whitespace\" \")))))((Secondary((id \ + 5460)(content(Whitespace\" \"))))(Tile((id \ + 5466)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5467)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5469)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5452)(content(Whitespace\" \")))))))))(Secondary((id \ + 5708)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5713)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5714)(content(Whitespace\" \"))))(Tile((id \ + 5717)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5718)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5755)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 5721)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5722)(content(Whitespace\" \"))))(Tile((id \ + 5753)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5747)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5748)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 5752)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 5730)(content(Whitespace\" \")))))((Secondary((id \ + 5732)(content(Whitespace\" \"))))(Tile((id \ + 5735)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5736)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5737)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5741)(content(Whitespace\" \")))))))))(Secondary((id \ + 5743)(content(Whitespace\" \"))))(Secondary((id \ + 2700)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5092)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5093)(content(Whitespace\" \"))))(Tile((id \ + 5167)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5171)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5180)(content(Whitespace\" \"))))(Tile((id \ + 5173)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5175)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5096)(content(Whitespace\" \")))))((Secondary((id \ + 5177)(content(Whitespace\" \"))))(Tile((id \ + 5179)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5098)(content(Whitespace\" \")))))))))(Secondary((id \ + 5103)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 5120)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 5208)(content(Comment\"#pat tests: \ + errors#\"))))(Secondary((id \ + 5522)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5527)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5528)(content(Whitespace\" \"))))(Tile((id \ + 5590)(label(2))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5555)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5594)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 5540)(content(Whitespace\" \")))))((Secondary((id \ + 5542)(content(Whitespace\" \"))))(Tile((id \ + 5596)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5551)(content(Whitespace\" \")))))))))(Secondary((id \ + 7273)(content(Whitespace\" \"))))(Secondary((id \ + 7801)(content(Comment\"#err: incons with \ + arrow#\"))))(Secondary((id \ + 5559)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5564)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5565)(content(Whitespace\" \"))))(Tile((id \ + 6317)(label(NotDefined))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5568)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5592)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 5571)(content(Whitespace\" \")))))((Secondary((id \ + 5573)(content(Whitespace\" \"))))(Tile((id \ + 5598)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5578)(content(Whitespace\" \")))))))))(Secondary((id \ + 5580)(content(Whitespace\" \"))))(Secondary((id \ + 7803)(content(Comment\"#err: cons \ + undefined#\"))))(Secondary((id \ + 5209)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5264)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5265)(content(Whitespace\" \"))))(Tile((id \ + 5268)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 5269)(content(Whitespace\" \")))))((Secondary((id \ + 5271)(content(Whitespace\" \"))))(Tile((id \ + 5285)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5277)(content(Whitespace\" \")))))))))(Secondary((id \ + 5279)(content(Whitespace\" \"))))(Secondary((id \ + 7805)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 5329)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5346)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5347)(content(Whitespace\" \"))))(Tile((id \ + 5350)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5351)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5377)(label(true))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 5354)(content(Whitespace\" \")))))((Secondary((id \ + 5356)(content(Whitespace\" \"))))(Tile((id \ + 5361)(label(Dawg))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5362)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5367)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5370)(content(Whitespace\" \")))))))))(Secondary((id \ + 7339)(content(Whitespace\" \"))))(Secondary((id \ + 7807)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 5470)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5475)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5476)(content(Whitespace\" \"))))(Tile((id \ + 5479)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5505)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5758)(content(Whitespace\" \"))))(Tile((id \ + 5512)(label(YoDawg))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5486)(content(Whitespace\" \")))))((Secondary((id \ + 5488)(content(Whitespace\" \"))))(Tile((id \ + 5518)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5519)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5521)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5502)(content(Whitespace\" \")))))))))(Secondary((id \ + 7358)(content(Whitespace\" \"))))(Secondary((id \ + 7809)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 5599)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5604)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5605)(content(Whitespace\" \"))))(Tile((id \ + 5608)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5663)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5665)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 5609)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5759)(content(Whitespace\" \"))))(Tile((id \ + 5666)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5669)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5617)(content(Whitespace\" \")))))((Secondary((id \ + 5619)(content(Whitespace\" \"))))(Tile((id \ + 5622)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 5628)(content(Whitespace\" \")))))))))(Secondary((id \ + 5630)(content(Whitespace\" \"))))(Secondary((id \ + 7811)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 5631)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5636)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 5637)(content(Whitespace\" \"))))(Tile((id \ + 5640)(label(Yo))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 5687)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 5703)(label(1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Tile((id \ + 5671)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5760)(content(Whitespace\" \"))))(Tile((id \ + 5673)(label(+))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5675)(label(Yo))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 5676)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 5697)(label(Bool))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 5649)(content(Whitespace\" \")))))((Secondary((id \ + 5651)(content(Whitespace\" \"))))(Tile((id \ + 5654)(label(Yo))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 5655)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 5702)(label(true))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 5660)(content(Whitespace\" \")))))))))(Secondary((id \ + 7395)(content(Whitespace\" \"))))(Secondary((id \ + 7813)(content(Comment\"#err: type \ + incons#\"))))(Secondary((id \ + 6564)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7846)(label(\"\\\"Thats all, folks\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2231)(content(Whitespace\"\\226\\143\\142\")))))))(ancestors())))(caret \ + Outer))"; + backup_text = + "#Non-recursive sum/alias tests#\n\ + #all lines with trailing err comment should have 1 error#\n\ + #no other lines should have errors#\n\n\ + #type definitions: no errors#\n\ + type = in\n\ + type SingleNull = +One in\n\ + type Single = +F(Int) in\n\ + type GoodSum = A + B + C(Int) in\n\ + type Partial = Ok( ) + in\n\ + type DoubleAlias = GoodSum in\n\ + type VerticalLeading =\n\ + + A\n\ + + B(GoodSum)\n\ + + C(Bool->Bool) \n\ + in\n\n\ + #incorrect or incomplete type definitions#\n\ + type badTypeName = in #err: invalid type name#\n\ + type ( , ) = in #err: invalid type name#\n\ + type = badTypeToken in #err: invalid type token#\n\ + type NotASum = NotInSum(Bool) in #err: cons not in sum#\n\ + type Bool = in #err: shadows base type#\n\ + type Dupes =\n\ + + Guy(Bool) #no err#\n\ + + Guy(Int) #err: already used#\n\ + + Guy in #err: already used#\n\ + type BadCons =\n\ + + Um(Unbound) #err: unbound type var#\n\ + + invalid #err: invalid#\n\ + + Bool #err: expected cons found type#\n\ + + Int(Int) #err: expected cons found type#\n\ + + ( )(Int) #err: expected cons found type#\n\ + + A(Bool)(Int) in #err: expected cons found app#\n\n\ + #sums in compound aliases dont add ctrs to scope#\n\ + #but compound alias types should propagate analytically#\n\ + type CompoundAlias = (Int, Anonymous + Sum) in \n\ + let _ = (1, Sum) in #err: not defined#\n\ + let _: CompoundAlias = (1, Sum) in #no error#\n\ + type Yorp = Int -> (Inside + Ouside) in\n\ + let _ = fun _ -> Inside in #err: not defined#\n\ + let _: Yorp = fun _ -> Inside in #no error#\n\ + type Gargs = [BigGuy + Small] in\n\ + let _ = BigGuy in #err: not defined#\n\ + let _: Gargs = [BigGuy] in #no error#\n\ + let _: Gargs = BigGuy :: [BigGuy] in #no error#\n\n\ + #unbound tyvars treated as unknown-typehole#\n\ + let a:Bad = 0 in a == 0; #err: not bound#\n\n\ + #non-sum-types cant be recursive#\n\ + type Lol = Lol in #err: not bound#\n\n\ + #no errors: analytic shadowing#\n\ + type Tork1 = +Blob in\n\ + type Tork2 = +Blob in \n\ + let x:Tork1 = Blob in\n\n\ + #exp tests: happy#\n\ + type YoDawg = Yo(Int) + Bo(Int)+ Dawg(Bool) in\n\ + let _ = Yo(1) in\n\ + let _ : YoDawg = Yo(2) in\n\ + let _ : +Yo(Bool) = Yo(true) in\n\ + let _ : (Yo + Dawg, Int) = (Dawg,5) in\n\ + let _ : DoubleAlias = C(4) in\n\n\ + #exp tests: errors#\n\ + let _ = 2(1) in #err: incons with arrow#\n\ + let _ = Undefined(1) in #err: cons undefined#\n\ + let _ = B(\"lol\") in #err: type incons#\n\ + let _ : +Yo(Bool) = Yo in #err: type incons#\n\ + let _ : +Yo = Yo(\"lol\") in #err: type incons#\n\ + let _ : +One = Yo(1) in #err: type incons#\n\n\ + #pat tests: happy (but refutable patterns so weird)#\n\ + let Yo = Bo in #kind of a weird edge#\n\ + let Yo(1) = Dawg(true) in\n\ + let Yo(1): YoDawg = Yo(1) in\n\ + let Yo(1): +Yo(Int) = Yo(1) in \n\ + let Yo: +Yo = Yo in\n\n\ + #pat tests: errors#\n\ + let 2(1) = 3 in #err: incons with arrow#\n\ + let NotDefined(1) = 3 in #err: cons undefined#\n\ + let Yo = Dawg in #err: type incons#\n\ + let Yo(true) = Dawg(true) in #err: type incons#\n\ + let Yo: YoDawg = Yo(1) in #err: type incons#\n\ + let Yo(1): +Yo = Yo in #err: type incons#\n\ + let Yo(1): +Yo(Bool) = Yo(true) in #err: type incons#\n\ + \"Thats all, folks\"\n"; + } ) ); + ( "ADT Dynamics", + ( 2482, + { + zipper = + "((selection((focus \ + Right)(content())))(backpack())(relatives((siblings(((Secondary((id \ + 2389)(content(Comment\"#recursive sum type dynamics \ + tests#\"))))(Secondary((id \ + 2390)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2467)(content(Comment\"#all calls should evaluate fully \ + with no exns or cast fails#\"))))(Secondary((id \ + 2352)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 337)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 338)(content(Whitespace\" \"))))(Tile((id \ + 342)(label(Exp))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 343)(content(Whitespace\" \")))))((Secondary((id \ + 2350)(content(Whitespace\" \"))))(Tile((id \ + 352)(label(Var))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 353)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 360)(label(String))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2351)(content(Whitespace\" \"))))(Tile((id \ + 362)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 364)(content(Whitespace\" \"))))(Tile((id \ + 2480)(label(Lam))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 371)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 378)(label(String))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 379)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 381)(content(Whitespace\" \"))))(Tile((id \ + 384)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 405)(content(Whitespace\" \")))))))))(Secondary((id \ + 2472)(content(Whitespace\"\\226\\143\\142\")))))((Secondary((id \ + 2097)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2102)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2103)(content(Whitespace\" \"))))(Tile((id \ + 2297)(label(s0))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2110)(content(Whitespace\" \"))))(Tile((id \ + 2111)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2112)(content(Whitespace\" \"))))(Tile((id \ + 2113)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Grout((id \ + 2116)(shape Convex)))(Tile((id 2115)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2117)(content(Whitespace\" \"))))(Grout((id 2120)(shape \ + Convex)))(Tile((id 2119)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2295)(content(Whitespace\" \"))))(Grout((id 2123)(shape \ + Convex))))))))(Secondary((id 2125)(content(Whitespace\" \ + \"))))(Tile((id 2127)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2128)(content(Whitespace\" \"))))(Grout((id 2294)(shape \ + Convex)))(Secondary((id 2133)(content(Whitespace\" \ + \")))))((Secondary((id 2135)(content(Whitespace\" \ + \"))))(Tile((id 2140)(label(fun ->))(mold((out \ + Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2141)(content(Whitespace\" \ + \"))))(Tile((id 2142)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2143)(label(e))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2145)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2146)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2148)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2149)(label(v))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 2151)(content(Whitespace\" \")))))))))(Secondary((id \ + 2154)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2160)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2161)(content(Whitespace\" \ + \"))))(Tile((id 2162)(label(e))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2164)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2165)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2166)(content(Whitespace\" \ + \"))))(Tile((id 2170)(label(Var))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 2171)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2172)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 2174)(content(Whitespace\" \")))))))))(Secondary((id \ + 2176)(content(Whitespace\" \"))))(Tile((id \ + 2177)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2181)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2182)(content(Whitespace\" \"))))(Tile((id \ + 2183)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2185)(content(Whitespace\" \"))))(Tile((id \ + 2188)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2189)(content(Whitespace\" \"))))(Tile((id \ + 2190)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2194)(content(Whitespace\" \")))))((Secondary((id \ + 2198)(content(Whitespace\" \"))))(Tile((id \ + 2199)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2203)(content(Whitespace\" \")))))))))(Secondary((id \ + 2207)(content(Whitespace\" \"))))(Tile((id \ + 2208)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2210)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2211)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2212)(content(Whitespace\" \ + \"))))(Tile((id 2216)(label(Lam))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 2217)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2218)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2220)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2221)(content(Whitespace\" \"))))(Tile((id \ + 2224)(label(e1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 2225)(content(Whitespace\" \")))))))))(Secondary((id \ + 2227)(content(Whitespace\" \"))))(Tile((id \ + 2228)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2232)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2233)(content(Whitespace\" \"))))(Tile((id \ + 2234)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2236)(content(Whitespace\" \"))))(Tile((id \ + 2239)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2240)(content(Whitespace\" \"))))(Tile((id \ + 2241)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2245)(content(Whitespace\" \")))))((Secondary((id \ + 2249)(content(Whitespace\" \"))))(Tile((id \ + 2250)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2254)(content(Whitespace\" \")))))))))(Secondary((id \ + 2258)(content(Whitespace\" \"))))(Tile((id \ + 2262)(label(Lam))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2263)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2264)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2266)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2267)(content(Whitespace\" \"))))(Tile((id \ + 2299)(label(s0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2274)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2277)(label(e1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2278)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2279)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2281)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2282)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ + 2286)(content(Whitespace\" \"))))(Secondary((id \ + 2284)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2291)(content(Whitespace\" \")))))))))(Secondary((id \ + 2293)(content(Whitespace\" \"))))(Secondary((id \ + 1804)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1809)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1810)(content(Whitespace\" \"))))(Tile((id \ + 2301)(label(s1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1817)(content(Whitespace\" \"))))(Tile((id \ + 1818)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1819)(content(Whitespace\" \"))))(Tile((id \ + 1820)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Grout((id \ + 2071)(shape Convex)))(Tile((id 1825)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1826)(content(Whitespace\" \"))))(Grout((id 1830)(shape \ + Convex)))(Tile((id 1829)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2072)(content(Whitespace\" \"))))(Grout((id 1833)(shape \ + Convex))))))))(Secondary((id 1835)(content(Whitespace\" \ + \"))))(Tile((id 1837)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1838)(content(Whitespace\" \"))))(Tile((id \ + 1842)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1843)(content(Whitespace\" \")))))((Secondary((id \ + 1845)(content(Whitespace\" \"))))(Tile((id 1850)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1851)(content(Whitespace\" \ + \"))))(Tile((id 1852)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1853)(label(e))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1855)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1856)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1858)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1859)(label(v))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1861)(content(Whitespace\" \")))))))))(Secondary((id \ + 1864)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1870)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1871)(content(Whitespace\" \ + \"))))(Tile((id 1872)(label(e))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1874)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1875)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1876)(content(Whitespace\" \ + \"))))(Tile((id 1880)(label(Var))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 1881)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1882)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1884)(content(Whitespace\" \")))))))))(Secondary((id \ + 1886)(content(Whitespace\" \"))))(Tile((id \ + 1887)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1891)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1892)(content(Whitespace\" \"))))(Tile((id \ + 1893)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1895)(content(Whitespace\" \"))))(Tile((id \ + 1898)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1899)(content(Whitespace\" \"))))(Tile((id \ + 1900)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1904)(content(Whitespace\" \")))))((Secondary((id \ + 1908)(content(Whitespace\" \"))))(Tile((id \ + 1909)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1913)(content(Whitespace\" \")))))))))(Secondary((id \ + 1917)(content(Whitespace\" \"))))(Tile((id \ + 1918)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1920)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1921)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1922)(content(Whitespace\" \ + \"))))(Tile((id 2078)(label(Lam))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 1930)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1931)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1933)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1934)(content(Whitespace\" \"))))(Tile((id \ + 1937)(label(e1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1938)(content(Whitespace\" \")))))))))(Secondary((id \ + 1940)(content(Whitespace\" \"))))(Tile((id \ + 1941)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1945)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1946)(content(Whitespace\" \"))))(Tile((id \ + 1947)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1949)(content(Whitespace\" \"))))(Tile((id \ + 1952)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1953)(content(Whitespace\" \"))))(Tile((id \ + 1954)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1958)(content(Whitespace\" \")))))((Secondary((id \ + 1962)(content(Whitespace\" \"))))(Tile((id \ + 1963)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1967)(content(Whitespace\" \")))))))))(Secondary((id \ + 1971)(content(Whitespace\" \"))))(Tile((id \ + 2075)(label(Lam))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1979)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1980)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1982)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1983)(content(Whitespace\" \"))))(Tile((id \ + 2303)(label(s1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1990)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1993)(label(e1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1994)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1995)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1997)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1998)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ + 2000)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2064)(content(Whitespace\" \")))))))))(Secondary((id \ + 2066)(content(Whitespace\" \"))))(Secondary((id \ + 1540)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1545)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1546)(content(Whitespace\" \"))))(Tile((id \ + 2305)(label(s2))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1553)(content(Whitespace\" \"))))(Tile((id \ + 1554)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1555)(content(Whitespace\" \"))))(Tile((id \ + 1556)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 1560)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 1561)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1562)(content(Whitespace\" \"))))(Grout((id 1565)(shape \ + Convex)))(Tile((id 1564)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1566)(content(Whitespace\" \"))))(Grout((id 1803)(shape \ + Convex))))))))(Secondary((id 1571)(content(Whitespace\" \ + \"))))(Tile((id 1573)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1574)(content(Whitespace\" \"))))(Tile((id \ + 1578)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1579)(content(Whitespace\" \")))))((Secondary((id \ + 1581)(content(Whitespace\" \"))))(Tile((id 1586)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1587)(content(Whitespace\" \ + \"))))(Tile((id 1588)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1589)(label(e))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1591)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1592)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1594)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1595)(label(v))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1597)(content(Whitespace\" \")))))))))(Secondary((id \ + 1600)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1606)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1607)(content(Whitespace\" \ + \"))))(Tile((id 1608)(label(e))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1610)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1611)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1612)(content(Whitespace\" \ + \"))))(Tile((id 1616)(label(Var))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 1617)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1618)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1620)(content(Whitespace\" \")))))))))(Secondary((id \ + 1622)(content(Whitespace\" \"))))(Tile((id \ + 1623)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1627)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1628)(content(Whitespace\" \"))))(Tile((id \ + 1629)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1631)(content(Whitespace\" \"))))(Tile((id \ + 1634)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1635)(content(Whitespace\" \"))))(Tile((id \ + 1636)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1640)(content(Whitespace\" \")))))((Secondary((id \ + 1644)(content(Whitespace\" \"))))(Tile((id \ + 1645)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1649)(content(Whitespace\" \")))))))))(Secondary((id \ + 1653)(content(Whitespace\" \"))))(Tile((id \ + 1654)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 1656)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1657)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1658)(content(Whitespace\" \ + \"))))(Tile((id 2081)(label(Lam))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 1666)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 1667)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 1669)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1670)(content(Whitespace\" \"))))(Tile((id \ + 1673)(label(e1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 1674)(content(Whitespace\" \")))))))))(Secondary((id \ + 1676)(content(Whitespace\" \"))))(Tile((id \ + 1677)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1681)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1682)(content(Whitespace\" \"))))(Tile((id \ + 1683)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1685)(content(Whitespace\" \"))))(Tile((id \ + 1688)(label($==))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 8))(sort \ + Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1689)(content(Whitespace\" \"))))(Tile((id \ + 1690)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1694)(content(Whitespace\" \")))))((Secondary((id \ + 1698)(content(Whitespace\" \"))))(Tile((id \ + 1699)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1703)(content(Whitespace\" \")))))))))(Secondary((id \ + 1707)(content(Whitespace\" \"))))(Tile((id \ + 2084)(label(Lam))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1715)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1716)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1718)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1719)(content(Whitespace\" \"))))(Tile((id \ + 2307)(label(s2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1726)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1729)(label(e1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1730)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1731)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1733)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1734)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ + 2068)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 1800)(content(Whitespace\" \")))))))))(Secondary((id \ + 1802)(content(Whitespace\" \"))))(Secondary((id \ + 410)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 414)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 415)(content(Whitespace\" \"))))(Tile((id \ + 2309)(label(s3))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 422)(content(Whitespace\" \"))))(Tile((id \ + 423)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 425)(content(Whitespace\" \"))))(Tile((id \ + 426)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 1209)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 430)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 432)(content(Whitespace\" \"))))(Grout((id 1215)(shape \ + Convex)))(Tile((id 434)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 994)(content(Whitespace\" \"))))(Tile((id \ + 1206)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 440)(content(Whitespace\" \"))))(Tile((id \ + 443)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 444)(content(Whitespace\" \"))))(Tile((id \ + 1292)(label(Exp))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 448)(content(Whitespace\" \")))))((Secondary((id \ + 451)(content(Whitespace\" \"))))(Tile((id 455)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 456)(content(Whitespace\" \ + \"))))(Tile((id 458)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 459)(label(e))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 460)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 462)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 463)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 465)(label(v))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 466)(content(Whitespace\" \")))))))))(Secondary((id \ + 470)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 475)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 476)(content(Whitespace\" \ + \"))))(Tile((id 478)(label(e))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 479)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 480)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 482)(content(Whitespace\" \ + \"))))(Tile((id 485)(label(Var))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 486)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 488)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 489)(content(Whitespace\" \")))))))))(Secondary((id \ + 492)(content(Whitespace\" \"))))(Tile((id \ + 493)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 496)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 497)(content(Whitespace\" \"))))(Tile((id \ + 499)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 500)(content(Whitespace\" \"))))(Tile((id \ + 504)(label($==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 505)(content(Whitespace\" \"))))(Tile((id \ + 506)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 509)(content(Whitespace\" \")))))((Secondary((id \ + 513)(content(Whitespace\" \"))))(Tile((id \ + 515)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 518)(content(Whitespace\" \")))))))))(Secondary((id \ + 522)(content(Whitespace\" \"))))(Tile((id \ + 1418)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 525)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 526)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 528)(content(Whitespace\" \ + \"))))(Tile((id 2087)(label(Lam))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 535)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 537)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 538)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 540)(content(Whitespace\" \"))))(Tile((id \ + 542)(label(e1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 543)(content(Whitespace\" \")))))))))(Secondary((id \ + 546)(content(Whitespace\" \"))))(Tile((id \ + 547)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 550)(label(if then else))(mold((out Exp)(in_(Exp \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 12))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 551)(content(Whitespace\" \"))))(Tile((id \ + 553)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 554)(content(Whitespace\" \"))))(Tile((id \ + 558)(label($==))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 8))(sort Exp))((shape(Concave 8))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 559)(content(Whitespace\" \"))))(Tile((id \ + 560)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 563)(content(Whitespace\" \")))))((Secondary((id \ + 567)(content(Whitespace\" \"))))(Tile((id \ + 569)(label(e))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 572)(content(Whitespace\" \")))))))))(Secondary((id \ + 576)(content(Whitespace\" \"))))(Tile((id \ + 2090)(label(Lam))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 584)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 586)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 587)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 589)(content(Whitespace\" \"))))(Tile((id \ + 2311)(label(s3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 595)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 598)(label(e1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 599)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 601)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 602)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 604)(label(v))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ + 605)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 669)(content(Whitespace\" \")))))))))(Secondary((id \ + 1308)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 902)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 906)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 907)(content(Whitespace\" \"))))(Tile((id \ + 1463)(label(in))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 914)(content(Whitespace\" \")))))((Secondary((id \ + 917)(content(Whitespace\" \"))))(Tile((id \ + 2478)(label(Lam))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1471)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1474)(label(\"\\\"b\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 1475)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1477)(content(Whitespace\" \"))))(Tile((id \ + 1480)(label(Var))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1481)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1484)(label(\"\\\"a\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Tile((id \ + 1485)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1488)(label(\"\\\"a\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 1489)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1493)(label(Var))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1494)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1497)(label(\"\\\"x\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 954)(content(Whitespace\" \")))))))))(Secondary((id \ + 956)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1539)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2313)(label(s0))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 1535)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 1538)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2348)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2349)(content(Whitespace\" \"))))(Tile((id \ + 2317)(label(s1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2318)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2321)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2322)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2339)(content(Whitespace\" \"))))(Tile((id \ + 2325)(label(s2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2326)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2329)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2330)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2340)(content(Whitespace\" \"))))(Tile((id \ + 2333)(label(s3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2334)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2337)(label(in))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 674)(content(Whitespace\"\\226\\143\\142\")))))))(ancestors())))(caret \ + Outer))"; + backup_text = + "#recursive sum type dynamics tests#\n\ + #all calls should evaluate fully with no exns or cast fails#\n\ + type Exp = Var(String) + Lam(String, Exp) in\n\n\ + let s0 : ( , , ) -> = fun (e,x,v) ->\n\ + case e\n\ + | Var(y) => (if y $== x then v else e)\n\ + | Lam(y, e1) => (if y $== x then e else Lam(y, s0(e1,x,v))) \n\ + end in \n\ + let s1 : ( , , ) -> Exp = fun (e,x,v) ->\n\ + case e\n\ + | Var(y) => (if y $== x then v else e)\n\ + | Lam(y, e1) => (if y $== x then e else Lam(y, s1(e1,x,v)))\n\ + end in \n\ + let s2 : (Exp, , ) -> Exp = fun (e,x,v) ->\n\ + case e\n\ + | Var(y) => (if y $== x then v else e)\n\ + | Lam(y, e1) => (if y $== x then e else Lam(y, s2(e1,x,v)))\n\ + end in \n\ + let s3 : (Exp, , Exp) -> Exp = fun (e,x,v) ->\n\ + case e\n\ + | Var(y) => (if y $== x then v else e)\n\ + | Lam(y, e1) => (if y $== x then e else Lam(y, s3(e1,x,v)))\n\ + end in\n\n\ + let in = Lam(\"b\", Var(\"a\")),\"a\",Var(\"x\") in\n\ + (s0(in), s1(in), s2(in), s3(in))\n"; + } ) ); + ] ); + } diff --git a/src/haz3lweb/Keyboard.re b/src/haz3lweb/Keyboard.re index 7ade716b6d..e5fb8c8e16 100644 --- a/src/haz3lweb/Keyboard.re +++ b/src/haz3lweb/Keyboard.re @@ -36,13 +36,29 @@ let handle_key_event = (k: Key.t, ~model: Model.t): list(Update.t) => { } | {key: D(key), sys: _, shift: Down, meta: Up, ctrl: Up, alt: Up} when is_f_key(key) => + let get_term = z => z |> Zipper.unselect_and_zip |> MakeTerm.go |> fst; switch (key) { - | "F2" => print(Zipper.show(zipper)) + | "F1" => zipper |> Zipper.show |> print + | "F2" => zipper |> Zipper.unselect_and_zip |> Segment.show |> print + | "F3" => zipper |> get_term |> TermBase.UExp.show |> print + | "F4" => zipper |> get_term |> Statics.mk_map |> Statics.Map.show |> print + | "F5" => + let term = zipper |> get_term; + let map = term |> Statics.mk_map; + Interface.get_result(map, term) |> ProgramResult.show |> print; | "F6" => - let (term, _) = MakeTerm.go(Zipper.unselect_and_zip(zipper)); - print(TermBase.UExp.show(term)); + let index = Indicated.index(zipper); + let map = zipper |> get_term |> Statics.mk_map; + switch (index) { + | Some(index) => + switch (Haz3lcore.Id.Map.find_opt(index, map)) { + | Some(ci) => print(Info.show(ci)) + | _ => print("DEBUG: No CI found for index") + } + | _ => print("DEBUG: No indicated index") + }; | _ => [] - } + }; | {key: D(key), sys: _, shift, meta: Up, ctrl: Up, alt: Up} => switch (shift, key) { | (Up, "ArrowLeft") => now(Move(Local(Left(ByChar)))) @@ -100,7 +116,7 @@ let handle_key_event = (k: Key.t, ~model: Model.t): list(Update.t) => { | "p" => now(Pick_up) | "a" => now(Move(Extreme(Up))) @ now(Select(Resize(Extreme(Down)))) | "k" => [ResetCurrentEditor] - | _ when is_digit(key) => [SwitchSlide(int_of_string(key))] + | _ when is_digit(key) => [SwitchScratchSlide(int_of_string(key))] | "ArrowLeft" => now(Move(Extreme(Left(ByToken)))) | "ArrowRight" => now(Move(Extreme(Right(ByToken)))) | "ArrowUp" => now(Move(Extreme(Up))) @@ -114,7 +130,7 @@ let handle_key_event = (k: Key.t, ~model: Model.t): list(Update.t) => { | "p" => now(Pick_up) | "a" => now(Move(Extreme(Up))) @ now(Select(Resize(Extreme(Down)))) | "k" => [ResetCurrentEditor] - | _ when is_digit(key) => [SwitchSlide(int_of_string(key))] + | _ when is_digit(key) => [SwitchScratchSlide(int_of_string(key))] | "ArrowLeft" => now(Move(Local(Left(ByToken)))) | "ArrowRight" => now(Move(Local(Right(ByToken)))) | "Home" => now(Move(Extreme(Up))) diff --git a/src/haz3lweb/LangDocMessages.re b/src/haz3lweb/LangDocMessages.re index da48cbc424..6b97e83872 100644 --- a/src/haz3lweb/LangDocMessages.re +++ b/src/haz3lweb/LangDocMessages.re @@ -48,6 +48,9 @@ let pat = v => Example.mk_monotile(Form.mk(Form.ss, [v], Mold.(mk_op(Pat, [])))); let typ = t => Example.mk_monotile(Form.mk(Form.ss, [t], Mold.(mk_op(Typ, [])))); +let tpat = v => + Example.mk_monotile(Form.mk(Form.ss, [v], Mold.(mk_op(TPat, [])))); +let typ_pat_var = t => Example.mk_monotile(Form.mk_atomic(TPat, t)); let int = n => Example.mk_monotile(Form.mk_atomic(Exp, n)); let bool = b => Example.mk_monotile(Form.mk_atomic(Exp, b)); let mk_parens_exp = Example.mk_tile(Form.get("parens_exp")); @@ -90,6 +93,8 @@ let mk_fun = Example.mk_tile(Form.get("fun_")); let mk_ap_exp = Example.mk_tile(Form.get("ap_exp")); let mk_ap_pat = Example.mk_tile(Form.get("ap_pat")); let mk_let = Example.mk_tile(Form.get("let_")); +let mk_tyalias = Example.mk_tile(Form.get("type_alias")); + let mk_if = Example.mk_tile(Form.get("if_")); let mk_test = Example.mk_tile(Form.get("test")); let mk_case = Example.mk_tile(Form.get("case")); @@ -105,34 +110,47 @@ let mk_example = str => { }; let empty_hole_exp_group = "empty_hole_exp_group"; -let empty_hole_exp: form = { +let empty_hole_tpat_group = "empty_hole_tpat_group"; +let empty_hole_template = (sort, str, id): form => { let explanation = { - message: "Empty hole. This marks an expression that needs to be filled in.", + message: + Printf.sprintf( + "Empty hole. This should be filled with %s to complete the program.", + str, + ), feedback: Unselected, }; { - id: "empty_hole_exp", - syntactic_form: [exp("EmptyHole")], + id, + syntactic_form: [sort("EmptyHole")], expandable_id: None, explanation, examples: [], }; }; +let empty_hole_exp: form = + empty_hole_template(exp, "an expression", "empty_hole_exp"); +let empty_hole_tpat: form = + empty_hole_template(tpat, "a type pattern", "empty_hole_tpat"); let multi_hole_exp_group = "multi_hole_exp_group"; -let multi_hole_exp: form = { +let multi_hole_tpat_group = "multi_hole_tpat_group"; + +let multi_hole_template = (sort, id: string): form => { let explanation = { message: "Not recognized. This is an invalid term.", feedback: Unselected, }; { - id: "multi_hole_exp", - syntactic_form: [exp("INVALID")], + id, + syntactic_form: [sort("INVALID")], expandable_id: None, explanation, examples: [], }; }; +let multi_hole_exp: form = multi_hole_template(exp, "multi_hole_exp"); +let multi_hole_tpat: form = multi_hole_template(tpat, "multi_hole_tpat"); let triv_exp_group = "triv_exp_group"; let triv_exp: form = { @@ -242,7 +260,7 @@ let function_var_group = "function_var_group"; let function_tuple_group = "function_tuple_group"; let function_tuple_2_group = "function_tuple_2_group"; let function_tuple_3_group = "function_tuple_3_group"; -let function_tag_group = "function_tag_group"; +let function_ctr_group = "function_ctr_group"; let function_ap_group = "function_ap_group"; let basic_fun_ex = { sub_id: "basic_fun_ex", @@ -334,8 +352,8 @@ let tuple3_fun_ex = { message: "When given a 3-tuple of booleans, the function evaluates to the logical-and of the three booleans.", feedback: Unselected, }; -let tag_fun_ex = { - sub_id: "tag_fun_ex", +let ctr_fun_ex = { + sub_id: "ctr_fun_ex", term: mk_example("fun None -> 1"), message: "When given a None constructor argument, the function evaluates 1.", feedback: Unselected, @@ -699,20 +717,20 @@ let function_tuple3_exp: form = { }; let _pat = pat("C"); let _exp = exp("e"); -let function_tag_exp_coloring_ids = +let function_ctr_exp_coloring_ids = _pat_body_function_exp_coloring_ids(Piece.id(_pat), Piece.id(_exp)); -let function_tag_exp: form = { +let function_ctr_exp: form = { let explanation = { message: "Function literal. The only value that matches the [*argument pattern*](%i) is the *`%s` constructor*. When applied to an argument which matches the [*argument pattern*](%i), evaluates to the function [*body*](%i).", feedback: Unselected, }; let form = [mk_fun([[space(), _pat, space()]]), space(), _exp]; { - id: "function_tag_exp", + id: "function_ctr_exp", syntactic_form: form, expandable_id: Some(Piece.id(_pat)), explanation, - examples: [tag_fun_ex], + examples: [ctr_fun_ex], }; }; let _pat_con = pat("p_con"); @@ -840,12 +858,15 @@ let var_exp: form = { }; }; -let tag_exp_group = "tag_exp_group"; -let tag_exp: form = { - let explanation = {message: "`%s` constructor.", feedback: Unselected}; +let ctr_exp_group = "ctr_exp_group"; +let ctr_exp: form = { + let explanation = { + message: "`%s` is a constructor for a sum type variant.", + feedback: Unselected, + }; { - id: "tag_exp", - syntactic_form: [exp("C")], + id: "ctr_exp", + syntactic_form: [exp("Constructor")], expandable_id: None, explanation, examples: [], @@ -854,7 +875,9 @@ let tag_exp: form = { let let_base_exp_group = "let_base_exp_group"; let let_empty_hole_exp_group = "let_empty_hole_exp_group"; +let let_empty_hole_tpat_group = "let_empty_hole_tpat_group"; let let_multi_hole_exp_group = "let_multi_hole_exp_group"; +let let_multi_hole_tpat_group = "let_multi_hole_tpat_group"; let let_wild_exp_group = "let_wild_hole_exp_group"; let let_int_exp_group = "let_int_exp_group"; let let_float_exp_group = "let_float_exp_group"; @@ -868,7 +891,7 @@ let let_var_exp_group = "let_var_exp_group"; let let_tuple_base_exp_group = "let_tuple_base_exp_group"; let let_tuple2_exp_group = "let_tuple2_exp_group"; let let_tuple3_exp_group = "let_tuple3_exp_group"; -let let_tag_exp_group = "let_tag_exp_group"; +let let_ctr_exp_group = "let_ctr_exp_group"; let let_ap_exp_group = "let_ap_exp_group"; let let_base_ex = { sub_id: "let_base_ex", @@ -954,8 +977,8 @@ let let_tuple3_ex = { message: "The x is bound to 1, the y is bound to 2, and the z is bound to 3, so the expression evaluates to 1 + 2 + 3, which is 6.", feedback: Unselected, }; -let let_tag_ex = { - sub_id: "let_tag_ex", +let let_ctr_ex = { + sub_id: "let_ctr_ex", term: mk_example("let None = None in \n2"), message: "The None is thrown away, so the expression evaluates to 2.", feedback: Unselected, @@ -1421,13 +1444,13 @@ let let_tuple3_exp: form = { let _pat = pat("C"); let _exp_def = exp("e_def"); let _exp_body = exp("e_body"); -let let_tag_exp_coloring_ids = +let let_ctr_exp_coloring_ids = _pat_def_body_let_exp_coloring_ids( Piece.id(_pat), Piece.id(_exp_def), Piece.id(_exp_body), ); -let let_tag_exp: form = { +let let_ctr_exp: form = { let explanation = { message: "Let expression. The only value for the [*definition*](%i) that matches the [*pattern*](%i) is the *`%s` constructor*. The [*definition*](%i) can't be referenced in the [*body*](%i).", feedback: Unselected, @@ -1438,11 +1461,11 @@ let let_tag_exp: form = { _exp_body, ]; { - id: "let_tag_exp", + id: "let_ctr_exp", syntactic_form: form, expandable_id: Some(Piece.id(_pat)), explanation, - examples: [let_tag_ex], + examples: [let_ctr_ex], }; }; let _pat_con = pat("p_con"); @@ -1477,6 +1500,32 @@ let let_ap_exp: form = { }; }; +let tyalias_exp_group = "tyalias_exp_group"; +let _tpat = tpat("p"); +let _typ_def = typ("ty_def"); +let tyalias_base_exp_coloring_ids = (~tpat_id: Id.t, ~def_id: Id.t) => [ + (Piece.id(_tpat), tpat_id), + (Piece.id(_typ_def), def_id), +]; +let tyalias_base_exp: form = { + let explanation = { + message: "Type alias expression. The [*type*](%i) is bound to the [*type variable*](%i) in the body.", + feedback: Unselected, + }; + let form = [ + mk_tyalias([[space(), _tpat, space()], [space(), _typ_def, space()]]), + linebreak(), + exp("e_body"), + ]; + { + id: "tyalias_base_exp", + syntactic_form: form, + expandable_id: None, + explanation, + examples: [], + }; +}; + let funapp_exp_group = "funapp_exp_group"; let conapp_exp_group = "conapp_exp_group"; let funapp_exp_ex = { @@ -2864,15 +2913,15 @@ let tuple_pat_size3: form = { }; }; -let tag_pat_group = "tag_pat_group"; -let tag_pat: form = { +let ctr_pat_group = "ctr_pat_group"; +let ctr_pat: form = { let explanation = { message: "Constructor pattern. Only expressions that match the *`%s` constructor* match this constructor pattern.", feedback: Unselected, }; { - id: "tag_pat", - syntactic_form: [pat("C")], + id: "ctr_pat", + syntactic_form: [pat("Constructor")], expandable_id: None, explanation, examples: [], @@ -3088,6 +3137,59 @@ let arrow3_typ: form = { }; }; +let labelled_sum_typ_group = "labelled_sum_typ_group"; +let labelled_sum_typ: form = { + let explanation = { + message: "Sum type. Sum types express finite labeled choices. Values of this type consist of one of the specified constructors applied to a parameter of the corresponding parameter type, if specified. Constructor names must be unique within a sum.", + feedback: Unselected, + }; + let divider = Example.mk_monotile(Form.get("typ_plus")); + { + id: "labelled_sum_typ", + syntactic_form: [ + space(), + typ("Cons(ty)"), + space(), + divider, + space(), + typ("..."), + space(), + ], + expandable_id: Some(Piece.id(divider)), + explanation, + examples: [], + }; +}; +let sum_typ_unary_constructor_def_group = "sum_typ_unary_constructor_def_group"; +let sum_typ_unary_constructor_def: form = { + let explanation = { + message: "Parameterized constructor definition. This specifies one possible way of constructing the parent sum type, when applied to a parameter of the specified parameter type.", + feedback: Unselected, + }; + { + id: "sum_typ_unary_constructor_def", + syntactic_form: [typ("Constructor(type)")], + expandable_id: None, + explanation, + examples: [], + }; +}; + +let sum_typ_nullary_constructor_def_group = "sum_typ_nullary_constructor_def_group"; +let sum_typ_nullary_constructor_def: form = { + let explanation = { + message: "Constant constructor definition. This specifies one possible way of constructing the parent sum type. It does not take an argument, so it a constant of that type.", + feedback: Unselected, + }; + { + id: "sum_typ_nullary_constructor_def", + syntactic_form: [typ("Constructor")], + expandable_id: None, + explanation, + examples: [], + }; +}; + let tuple_typ_group = "tuple_typ_group"; let tuple2_typ_group = "tuple2_typ_group"; let tuple3_typ_group = "tuple3_typ_group"; @@ -3160,10 +3262,28 @@ let tuple3_typ: form = { let var_typ_group = "var_typ_group"; let var_typ: form = { - let explanation = {message: "`%s` type.", feedback: Unselected}; + let explanation = { + message: "`%s` is a type variable.", + feedback: Unselected, + }; { id: "var_typ", - syntactic_form: [typ("x")], + syntactic_form: [typ("T")], + expandable_id: None, + explanation, + examples: [], + }; +}; + +let var_typ_pat_group = "var_typ_pat_group"; +let var_typ_pat: form = { + let explanation = { + message: "`%s` binds a type variable.", + feedback: Unselected, + }; + { + id: "var_typ_pat", + syntactic_form: [typ_pat_var("T")], expandable_id: None, explanation, examples: [], @@ -3181,25 +3301,40 @@ type t = { groups: list((string, form_group)), }; +let find = (p: 'a => bool, xs: list('a), err: string): 'a => + switch (List.find_opt(p, xs)) { + | Some(x) => x + | None => failwith(err) + }; + let get_group = (group_id, doc: t) => { - let (_, form_group) = List.find(((id, _)) => id == group_id, doc.groups); + let (_, form_group) = + find( + ((id, _)) => id == group_id, + doc.groups, + "group not found: " ++ group_id, + ); form_group; }; +let get_form = (form_id, docs) => + find(({id, _}) => id == form_id, docs, "form not found: " ++ form_id); + +let get_example = (example_sub_id, examples) => + find( + ({sub_id, _}) => sub_id == example_sub_id, + examples, + "example not found: " ++ example_sub_id, + ); + let get_form_and_options = (group_id, doc: t) => { let form_group = get_group(group_id, doc); let (selected_id, _) = List.nth(form_group.options, form_group.current_selection); - let form = List.find(({id, _}) => id == selected_id, doc.forms); + let form = get_form(selected_id, doc.forms); (form, form_group.options); }; -let get_example = (example_sub_id, examples) => - List.find(({sub_id, _}) => sub_id == example_sub_id, examples); - -let get_form = (form_id, docs) => - List.find(({id, _}) => id == form_id, docs); - let rec update_form = (new_form, docs) => { switch (docs) { | [] => [] @@ -3246,12 +3381,14 @@ let init_options = options => { let init = { show: true, - highlight: true, + highlight: false, specificity_open: false, forms: [ // Expressions empty_hole_exp, + empty_hole_tpat, multi_hole_exp, + multi_hole_tpat, triv_exp, bool_exp, int_exp, @@ -3274,13 +3411,13 @@ let init = { function_tuple_exp, function_tuple2_exp, function_tuple3_exp, - function_tag_exp, + function_ctr_exp, function_ap_exp, tuple_exp, tuple_exp_size2, tuple_exp_size3, var_exp, - tag_exp, + ctr_exp, let_base_exp, let_empty_hole_exp, let_multi_hole_exp, @@ -3297,8 +3434,9 @@ let init = { let_tuple_exp, let_tuple2_exp, let_tuple3_exp, - let_tag_exp, + let_ctr_exp, let_ap_exp, + tyalias_base_exp, funapp_exp, conapp_exp, if_exp, @@ -3348,7 +3486,7 @@ let init = { tuple_pat, tuple_pat_size2, tuple_pat_size3, - tag_pat, + ctr_pat, ap_pat, typann_pat, // Types @@ -3361,15 +3499,21 @@ let init = { list_typ, arrow_typ, arrow3_typ, + labelled_sum_typ, + sum_typ_unary_constructor_def, + sum_typ_nullary_constructor_def, tuple_typ, tuple2_typ, tuple3_typ, var_typ, + var_typ_pat, ], groups: [ // Expressions (empty_hole_exp_group, init_options([(empty_hole_exp.id, [])])), + (empty_hole_tpat_group, init_options([(empty_hole_tpat.id, [])])), (multi_hole_exp_group, init_options([(multi_hole_exp.id, [])])), + (multi_hole_tpat_group, init_options([(multi_hole_tpat.id, [])])), (triv_exp_group, init_options([(triv_exp.id, [])])), (bool_exp_group, init_options([(bool_exp.id, [])])), (int_exp_group, init_options([(int_exp.id, [])])), @@ -3491,10 +3635,10 @@ let init = { ]), ), ( - function_tag_group, + function_ctr_group, init_options([ (function_exp.id, [pat("p")]), - (function_tag_exp.id, [pat("C")]), + (function_ctr_exp.id, [pat("C")]), ]), ), ( @@ -3526,7 +3670,7 @@ let init = { ]), ), (var_exp_group, init_options([(var_exp.id, [])])), - (tag_exp_group, init_options([(tag_exp.id, [])])), + (ctr_exp_group, init_options([(ctr_exp.id, [])])), (let_base_exp_group, init_options([(let_base_exp.id, [])])), ( let_empty_hole_exp_group, @@ -3639,10 +3783,10 @@ let init = { ]), ), ( - let_tag_exp_group, + let_ctr_exp_group, init_options([ (let_base_exp.id, [pat("p")]), - (let_tag_exp.id, [pat("C")]), + (let_ctr_exp.id, [pat("C")]), ]), ), ( @@ -3652,6 +3796,7 @@ let init = { (let_ap_exp.id, [pat("p_con"), mk_ap_pat([[pat("p_arg")]])]), ]), ), + (tyalias_exp_group, init_options([(tyalias_base_exp.id, [])])), (funapp_exp_group, init_options([(funapp_exp.id, [])])), (conapp_exp_group, init_options([(conapp_exp.id, [])])), (if_exp_group, init_options([(if_exp.id, [])])), @@ -3722,7 +3867,7 @@ let init = { ), ]), ), - (tag_pat_group, init_options([(tag_pat.id, [])])), + (ctr_pat_group, init_options([(ctr_pat.id, [])])), (ap_pat_group, init_options([(ap_pat.id, [])])), (typann_pat_group, init_options([(typann_pat.id, [])])), // Types @@ -3741,6 +3886,15 @@ let init = { (arrow3_typ.id, [typ("ty_arg2"), arrow(), typ("ty_out")]), ]), ), + (labelled_sum_typ_group, init_options([(labelled_sum_typ.id, [])])), + ( + sum_typ_unary_constructor_def_group, + init_options([(sum_typ_unary_constructor_def.id, [])]), + ), + ( + sum_typ_nullary_constructor_def_group, + init_options([(sum_typ_nullary_constructor_def.id, [])]), + ), (tuple_typ_group, init_options([(tuple_typ.id, [])])), ( tuple2_typ_group, @@ -3760,6 +3914,7 @@ let init = { ]), ), (var_typ_group, init_options([(var_typ.id, [])])), + (var_typ_pat_group, init_options([(var_typ_pat.id, [])])), ], }; diff --git a/src/haz3lweb/LanguageRefSlide.ml b/src/haz3lweb/LanguageRefSlide.ml deleted file mode 100644 index 827279da11..0000000000 --- a/src/haz3lweb/LanguageRefSlide.ml +++ /dev/null @@ -1,1069 +0,0 @@ -let slide : ScratchSlide.persistent_state = - ( 3588, - { - zipper = - "((selection((focus \ - Left)(content())))(backpack())(relatives((siblings(((Secondary((id \ - 2915)(content(Comment\"# Hazel Language Quick Reference \ - #\")))))((Secondary((id \ - 3020)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3021)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3150)(content(Comment\"# Empty holes stand for missing expressions, \ - patterns, or types #\"))))(Secondary((id \ - 3030)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 3035)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 3036)(content(Whitespace\" \ - \"))))(Tile((id 3047)(label(empty_hole))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 3048)(content(Whitespace\" \")))))((Secondary((id \ - 3052)(content(Whitespace\" \"))))(Grout((id 3051)(shape \ - Convex)))(Secondary((id 3050)(content(Whitespace\" \ - \")))))))))(Secondary((id \ - 3151)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3152)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2840)(content(Comment\"# Integers #\"))))(Secondary((id \ - 2829)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1498)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1499)(content(Whitespace\" \ - \"))))(Tile((id 1508)(label(int_lits))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1509)(content(Whitespace\" \"))))(Tile((id 1510)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 1512)(content(Whitespace\" \"))))(Tile((id \ - 1515)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1516)(content(Whitespace\" \")))))((Secondary((id \ - 1519)(content(Whitespace\" \"))))(Tile((id 1520)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1523)(content(Whitespace\" \")))))))))(Secondary((id \ - 1525)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1530)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1531)(content(Whitespace\" \ - \"))))(Tile((id 1540)(label(negation))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1541)(content(Whitespace\" \")))))((Secondary((id \ - 1544)(content(Whitespace\" \"))))(Tile((id 1545)(label(-))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape(Concave 2))(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1546)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1549)(content(Whitespace\" \")))))))))(Secondary((id \ - 1551)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1556)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1557)(content(Whitespace\" \ - \"))))(Tile((id 1568)(label(arithmetic))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1569)(content(Whitespace\" \")))))((Secondary((id \ - 1572)(content(Whitespace\" \"))))(Tile((id 1573)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1574)(label(*))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 4))(sort Exp))((shape(Concave \ - 4))(sort Exp))))))(shards(0))(children())))(Tile((id \ - 1576)(label(2))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1577)(content(Whitespace\" \"))))(Tile((id 1578)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1580)(content(Whitespace\" \"))))(Tile((id 1581)(label(8))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1582)(label(/))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 4))(sort Exp))((shape(Concave \ - 4))(sort Exp))))))(shards(0))(children())))(Tile((id \ - 1584)(label(4))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1587)(content(Whitespace\" \")))))))))(Secondary((id \ - 1589)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1594)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1595)(content(Whitespace\" \ - \"))))(Tile((id 1610)(label(int_comparison))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1611)(content(Whitespace\" \")))))((Secondary((id \ - 1614)(content(Whitespace\" \"))))(Tile((id \ - 1615)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 1617)(label(10))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1618)(content(Whitespace\" \"))))(Tile((id 1621)(label(==))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 8))(sort Exp))((shape(Concave \ - 8))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1622)(content(Whitespace\" \"))))(Tile((id 1624)(label(10))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1625)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1627)(content(Whitespace\" \"))))(Tile((id 1628)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1629)(content(Whitespace\" \"))))(Tile((id 1630)(label(<))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1632)(content(Whitespace\" \"))))(Tile((id 1633)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1634)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1636)(content(Whitespace\" \"))))(Tile((id 1637)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1638)(content(Whitespace\" \"))))(Tile((id 1641)(label(<=))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 8))(sort Exp))((shape(Concave \ - 8))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1642)(content(Whitespace\" \"))))(Tile((id 1643)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1644)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1646)(content(Whitespace\" \"))))(Tile((id 1647)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1648)(content(Whitespace\" \"))))(Tile((id 1649)(label(>))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1651)(content(Whitespace\" \"))))(Tile((id 1652)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1653)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1655)(content(Whitespace\" \"))))(Tile((id 1656)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1657)(content(Whitespace\" \"))))(Tile((id 1660)(label(>=))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 8))(sort Exp))((shape(Concave \ - 8))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1661)(content(Whitespace\" \"))))(Tile((id 1662)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 1665)(content(Whitespace\" \")))))))))(Secondary((id \ - 3353)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2841)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2866)(content(Comment\"# Floating Point Numbers #\"))))(Secondary((id \ - 1669)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1673)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1674)(content(Whitespace\" \ - \"))))(Tile((id 1685)(label(float_lits))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1686)(content(Whitespace\" \"))))(Tile((id 1687)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 1689)(content(Whitespace\" \"))))(Tile((id \ - 1694)(label(Float))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1695)(content(Whitespace\" \")))))((Secondary((id \ - 1698)(content(Whitespace\" \"))))(Tile((id \ - 1701)(label(1.5))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1704)(content(Whitespace\" \")))))))))(Secondary((id \ - 1706)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1711)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1712)(content(Whitespace\" \ - \"))))(Tile((id 1724)(label(float_artih))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1725)(content(Whitespace\" \")))))((Secondary((id \ - 1728)(content(Whitespace\" \"))))(Tile((id 1730)(label(1.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1731)(content(Whitespace\" \"))))(Tile((id 1734)(label(*.))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 4))(sort Exp))((shape(Concave \ - 4))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1735)(content(Whitespace\" \"))))(Tile((id 1737)(label(2.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1738)(content(Whitespace\" \"))))(Tile((id 1741)(label(+.))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1742)(content(Whitespace\" \"))))(Tile((id 1744)(label(8.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1745)(content(Whitespace\" \"))))(Tile((id 1748)(label(/.))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 4))(sort Exp))((shape(Concave \ - 4))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1749)(content(Whitespace\" \"))))(Tile((id 1751)(label(4.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1754)(content(Whitespace\" \")))))))))(Secondary((id \ - 1756)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1761)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1762)(content(Whitespace\" \ - \"))))(Tile((id 1779)(label(float_comparison))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1780)(content(Whitespace\" \")))))((Secondary((id \ - 1783)(content(Whitespace\" \"))))(Tile((id \ - 1784)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 1787)(label(10.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1788)(content(Whitespace\" \"))))(Tile((id \ - 1792)(label(==.))(mold((out Exp)(in_())(nibs(((shape(Concave 8))(sort \ - Exp))((shape(Concave 8))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1793)(content(Whitespace\" \"))))(Tile((id \ - 1796)(label(10.))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 1797)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave 14))(sort \ - Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1799)(content(Whitespace\" \"))))(Tile((id 1801)(label(1.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1802)(content(Whitespace\" \"))))(Tile((id 1805)(label(<.))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1806)(content(Whitespace\" \"))))(Tile((id 1808)(label(2.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1809)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1811)(content(Whitespace\" \"))))(Tile((id 1813)(label(2.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1814)(content(Whitespace\" \"))))(Tile((id \ - 1818)(label(<=.))(mold((out Exp)(in_())(nibs(((shape(Concave 8))(sort \ - Exp))((shape(Concave 8))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1819)(content(Whitespace\" \"))))(Tile((id 1821)(label(3.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1822)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1824)(content(Whitespace\" \"))))(Tile((id 1826)(label(3.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1827)(content(Whitespace\" \"))))(Tile((id 1830)(label(>.))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1831)(content(Whitespace\" \"))))(Tile((id 1833)(label(2.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1834)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1836)(content(Whitespace\" \"))))(Tile((id 1838)(label(2.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1839)(content(Whitespace\" \"))))(Tile((id \ - 1843)(label(>=.))(mold((out Exp)(in_())(nibs(((shape(Concave 8))(sort \ - Exp))((shape(Concave 8))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1844)(content(Whitespace\" \"))))(Tile((id 1846)(label(1.))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 1849)(content(Whitespace\" \")))))))))(Secondary((id \ - 1851)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2867)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2878)(content(Comment\"# Booleans #\"))))(Secondary((id \ - 1853)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1857)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1858)(content(Whitespace\" \ - \"))))(Tile((id 1867)(label(booleans))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1868)(content(Whitespace\" \"))))(Tile((id 1869)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 1871)(content(Whitespace\" \"))))(Tile((id \ - 1872)(label(\"(\"\")\"))(mold((out Typ)(in_(Typ))(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 1876)(label(Bool))(mold((out \ - Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id 1877)(label(,))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 14))(sort Typ))((shape(Concave \ - 14))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 1879)(content(Whitespace\" \"))))(Tile((id \ - 1883)(label(Bool))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 1884)(content(Whitespace\" \")))))((Secondary((id \ - 1887)(content(Whitespace\" \"))))(Tile((id \ - 1888)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 1892)(label(true))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1893)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1895)(content(Whitespace\" \"))))(Tile((id \ - 1900)(label(false))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 1903)(content(Whitespace\" \")))))))))(Secondary((id \ - 1905)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1910)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1911)(content(Whitespace\" \ - \"))))(Tile((id 1924)(label(conditionals))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1925)(content(Whitespace\" \")))))((Secondary((id \ - 1928)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1932)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1933)(content(Whitespace\" \ - \"))))(Tile((id 1935)(label(\"(\"\")\"))(mold((out \ - Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0 1))(children(((Tile((id 1936)(label(x))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 1937)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 1939)(content(Whitespace\" \"))))(Tile((id 1940)(label(y))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children()))))))))(Secondary((id \ - 1941)(content(Whitespace\" \")))))((Secondary((id \ - 1944)(content(Whitespace\" \"))))(Tile((id \ - 1945)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 1946)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1947)(content(Whitespace\" \"))))(Tile((id 1948)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1950)(content(Whitespace\" \"))))(Tile((id 1951)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1952)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1954)(content(Whitespace\" \"))))(Tile((id 1955)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1956)(content(Whitespace\" \"))))(Tile((id 1957)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1959)(content(Whitespace\" \"))))(Tile((id 1960)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 1963)(content(Whitespace\" \")))))))))(Secondary((id \ - 1965)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1969)(label(if then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 12))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 1970)(content(Whitespace\" \ - \"))))(Tile((id 1972)(label(y))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1973)(content(Whitespace\" \"))))(Tile((id 1974)(label(>))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 1976)(content(Whitespace\" \"))))(Tile((id 1977)(label(x))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1980)(content(Whitespace\" \")))))((Secondary((id \ - 1984)(content(Whitespace\" \"))))(Tile((id 1986)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1991)(content(Whitespace\" \"))))(Secondary((id \ - 1987)(content(Whitespace\" \"))))(Secondary((id \ - 1988)(content(Whitespace\" \"))))(Secondary((id \ - 1989)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 1995)(content(Whitespace\" \"))))(Tile((id 1997)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2002)(content(Whitespace\" \"))))(Secondary((id \ - 1998)(content(Whitespace\" \"))))(Secondary((id \ - 1999)(content(Whitespace\" \"))))(Secondary((id \ - 2000)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2004)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2916)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2925)(content(Comment\"# Tuples #\"))))(Secondary((id \ - 2006)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2010)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2011)(content(Whitespace\" \ - \"))))(Tile((id 2018)(label(tuples))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2019)(content(Whitespace\" \"))))(Tile((id 2020)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2022)(content(Whitespace\" \"))))(Tile((id \ - 2023)(label(\"(\"\")\"))(mold((out Typ)(in_(Typ))(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2026)(label(Int))(mold((out \ - Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id 2027)(label(,))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 14))(sort Typ))((shape(Concave \ - 14))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2029)(content(Whitespace\" \"))))(Tile((id \ - 2033)(label(Bool))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ - 2034)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave 14))(sort \ - Typ))((shape(Concave 14))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2036)(content(Whitespace\" \"))))(Tile((id \ - 2037)(label(\"(\"\")\"))(mold((out Typ)(in_(Typ))(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2041)(label(Bool))(mold((out \ - Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id 2042)(label(,))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 14))(sort Typ))((shape(Concave \ - 14))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2044)(content(Whitespace\" \"))))(Tile((id \ - 2047)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ - 2048)(content(Whitespace\" \")))))((Secondary((id \ - 2051)(content(Whitespace\" \"))))(Tile((id \ - 2052)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2053)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2054)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2056)(content(Whitespace\" \"))))(Tile((id \ - 2060)(label(true))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 2061)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave 14))(sort \ - Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2063)(content(Whitespace\" \"))))(Tile((id \ - 2064)(label(\"(\"\")\"))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2069)(label(false))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2070)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2072)(content(Whitespace\" \"))))(Tile((id 2073)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ - 2076)(content(Whitespace\" \")))))))))(Secondary((id \ - 2078)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2083)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2084)(content(Whitespace\" \ - \"))))(Tile((id 2086)(label(\"(\"\")\"))(mold((out \ - Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0 1))(children(((Tile((id 2087)(label(a))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2088)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2090)(content(Whitespace\" \"))))(Tile((id 2091)(label(b))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2092)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2094)(content(Whitespace\" \"))))(Tile((id \ - 2095)(label(\"(\"\")\"))(mold((out Pat)(in_(Pat))(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort Pat))))))(shards(0 \ - 1))(children(((Tile((id 2096)(label(c))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2097)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2099)(content(Whitespace\" \"))))(Tile((id 2100)(label(d))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))))))))))))(Secondary((id \ - 2101)(content(Whitespace\" \")))))((Secondary((id \ - 2104)(content(Whitespace\" \"))))(Tile((id \ - 2110)(label(tuples))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2113)(content(Whitespace\" \")))))))))(Secondary((id \ - 2115)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2926)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2938)(content(Comment\"# Functions #\"))))(Secondary((id \ - 2117)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2121)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2122)(content(Whitespace\" \ - \"))))(Tile((id 2124)(label(y))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2125)(content(Whitespace\" \"))))(Tile((id 2126)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2128)(content(Whitespace\" \"))))(Tile((id \ - 2129)(label(\"(\"\")\"))(mold((out Typ)(in_(Typ))(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2132)(label(Int))(mold((out \ - Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id 2133)(label(,))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 14))(sort Typ))((shape(Concave \ - 14))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2135)(content(Whitespace\" \"))))(Tile((id \ - 2138)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ - 2139)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave 14))(sort \ - Typ))((shape(Concave 14))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2141)(content(Whitespace\" \"))))(Tile((id \ - 2144)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2145)(content(Whitespace\" \"))))(Tile((id 2148)(label(->))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 6))(sort Typ))((shape(Concave \ - 6))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2149)(content(Whitespace\" \"))))(Tile((id \ - 2152)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2153)(content(Whitespace\" \")))))((Secondary((id \ - 2156)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2160)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2161)(content(Whitespace\" \ - \"))))(Tile((id 2163)(label(\"(\"\")\"))(mold((out \ - Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0 1))(children(((Tile((id 2164)(label(m))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2165)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2167)(content(Whitespace\" \"))))(Tile((id 2168)(label(x))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2169)(label(,))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 14))(sort Pat))((shape(Concave \ - 14))(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2171)(content(Whitespace\" \"))))(Tile((id 2172)(label(b))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children()))))))))(Secondary((id \ - 2173)(content(Whitespace\" \")))))))))(Secondary((id \ - 2177)(content(Whitespace\" \"))))(Tile((id 2178)(label(m))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2179)(content(Whitespace\" \"))))(Tile((id 2180)(label(*))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 4))(sort Exp))((shape(Concave \ - 4))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2182)(content(Whitespace\" \"))))(Tile((id 2183)(label(x))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2184)(content(Whitespace\" \"))))(Tile((id 2185)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2187)(content(Whitespace\" \"))))(Tile((id 2188)(label(b))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2193)(content(Whitespace\" \"))))(Secondary((id \ - 2189)(content(Whitespace\" \"))))(Secondary((id \ - 2190)(content(Whitespace\" \"))))(Secondary((id \ - 2191)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2195)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2939)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2998)(content(Comment\"# Recursive Functions (arrow type annotation \ - required) #\"))))(Secondary((id \ - 2197)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2201)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2202)(content(Whitespace\" \ - \"))))(Tile((id 2221)(label(double_recursively))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2222)(content(Whitespace\" \"))))(Tile((id 2223)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2225)(content(Whitespace\" \"))))(Tile((id \ - 2228)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2229)(content(Whitespace\" \"))))(Tile((id 2232)(label(->))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 6))(sort Typ))((shape(Concave \ - 6))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2233)(content(Whitespace\" \"))))(Tile((id \ - 2236)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2237)(content(Whitespace\" \")))))((Secondary((id \ - 2240)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2244)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2245)(content(Whitespace\" \ - \"))))(Tile((id 2247)(label(n))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2248)(content(Whitespace\" \")))))))))(Secondary((id \ - 2252)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2255)(label(if then else))(mold((out Exp)(in_(Exp Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 12))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2256)(content(Whitespace\" \ - \"))))(Tile((id 2258)(label(n))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2259)(content(Whitespace\" \"))))(Tile((id 2262)(label(==))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 8))(sort Exp))((shape(Concave \ - 8))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2263)(content(Whitespace\" \"))))(Tile((id 2264)(label(0))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2267)(content(Whitespace\" \")))))((Secondary((id \ - 2271)(content(Whitespace\" \"))))(Tile((id 2273)(label(0))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2278)(content(Whitespace\" \"))))(Secondary((id \ - 2274)(content(Whitespace\" \"))))(Secondary((id \ - 2275)(content(Whitespace\" \"))))(Secondary((id \ - 2276)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2282)(content(Whitespace\" \"))))(Tile((id \ - 2301)(label(double_recursively))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2302)(label(\"(\"\")\"))(mold((out \ - Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ - Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2304)(label(n))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2305)(content(Whitespace\" \"))))(Tile((id 2306)(label(-))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2308)(content(Whitespace\" \"))))(Tile((id 2309)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 2310)(content(Whitespace\" \"))))(Tile((id 2311)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2313)(content(Whitespace\" \"))))(Tile((id 2314)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2319)(content(Whitespace\" \"))))(Secondary((id \ - 2315)(content(Whitespace\" \"))))(Secondary((id \ - 2316)(content(Whitespace\" \"))))(Secondary((id \ - 2317)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2321)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2999)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3007)(content(Comment\"# Lists #\"))))(Secondary((id \ - 2323)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2327)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2328)(content(Whitespace\" \ - \"))))(Tile((id 2339)(label(empty_list))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2340)(content(Whitespace\" \"))))(Tile((id 2341)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2343)(content(Whitespace\" \"))))(Tile((id 2344)(label([ \ - ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2347)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2348)(content(Whitespace\" \")))))((Secondary((id \ - 2351)(content(Whitespace\" \"))))(Tile((id 2354)(label([]))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2357)(content(Whitespace\" \")))))))))(Secondary((id \ - 2359)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2364)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2365)(content(Whitespace\" \ - \"))))(Tile((id 2380)(label(non_empty_list))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2381)(content(Whitespace\" \"))))(Tile((id 2382)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2384)(content(Whitespace\" \"))))(Tile((id 2385)(label([ \ - ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2388)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2389)(content(Whitespace\" \")))))((Secondary((id \ - 2392)(content(Whitespace\" \"))))(Tile((id 2393)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2396)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave 6))(sort \ - Exp))((shape(Concave 6))(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2397)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2400)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave 6))(sort \ - Exp))((shape(Concave 6))(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2401)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2404)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave 6))(sort \ - Exp))((shape(Concave 6))(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2407)(label([]))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2410)(content(Whitespace\" \")))))))))(Secondary((id \ - 2412)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2417)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2418)(content(Whitespace\" \ - \"))))(Tile((id 2432)(label(list_literals))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2433)(content(Whitespace\" \"))))(Tile((id 2434)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2436)(content(Whitespace\" \"))))(Tile((id 2437)(label([ \ - ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2440)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2441)(content(Whitespace\" \")))))((Secondary((id \ - 2444)(content(Whitespace\" \"))))(Tile((id 2445)(label([ \ - ]))(mold((out Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ - Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2446)(label(1))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 2447)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave 14))(sort \ - Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2449)(content(Whitespace\" \"))))(Tile((id 2450)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2451)(label(,))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 14))(sort Exp))((shape(Concave \ - 14))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2453)(content(Whitespace\" \"))))(Tile((id 2454)(label(3))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 2457)(content(Whitespace\" \")))))))))(Secondary((id \ - 2459)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2464)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2465)(content(Whitespace\" \ - \"))))(Tile((id 2472)(label(length))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2473)(content(Whitespace\" \"))))(Tile((id 2474)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2476)(content(Whitespace\" \"))))(Tile((id 2477)(label([ \ - ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2480)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2481)(content(Whitespace\" \"))))(Tile((id 2484)(label(->))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 6))(sort Typ))((shape(Concave \ - 6))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2485)(content(Whitespace\" \"))))(Tile((id \ - 2488)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2489)(content(Whitespace\" \")))))((Secondary((id \ - 2492)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2496)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2497)(content(Whitespace\" \ - \"))))(Tile((id 2500)(label(xs))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2501)(content(Whitespace\" \")))))))))(Secondary((id \ - 2505)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2510)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2511)(content(Whitespace\" \ - \"))))(Tile((id 2514)(label(xs))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2515)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2516)(label(| =>))(mold((out Rul)(in_(Pat))(nibs(((shape(Concave \ - 19))(sort Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2518)(content(Whitespace\" \ - \"))))(Tile((id 2521)(label([]))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2522)(content(Whitespace\" \")))))))))(Secondary((id \ - 2525)(content(Whitespace\" \"))))(Tile((id 2526)(label(0))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2527)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2528)(label(| =>))(mold((out Rul)(in_(Pat))(nibs(((shape(Concave \ - 19))(sort Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2530)(content(Whitespace\" \ - \"))))(Tile((id 2532)(label(hd))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2535)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave 6))(sort \ - Pat))((shape(Concave 6))(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2537)(label(tl))(mold((out Pat)(in_())(nibs(((shape Convex)(sort \ - Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2538)(content(Whitespace\" \")))))))))(Secondary((id \ - 2541)(content(Whitespace\" \"))))(Tile((id 2542)(label(1))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2543)(content(Whitespace\" \"))))(Tile((id 2544)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2546)(content(Whitespace\" \"))))(Tile((id \ - 2552)(label(length))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 2553)(label(\"(\"\")\"))(mold((out \ - Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ - Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2556)(label(tl))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 2561)(content(Whitespace\" \"))))(Secondary((id \ - 2557)(content(Whitespace\" \"))))(Secondary((id \ - 2558)(content(Whitespace\" \"))))(Secondary((id \ - 2559)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2568)(content(Whitespace\" \"))))(Secondary((id \ - 2564)(content(Whitespace\" \"))))(Secondary((id \ - 2565)(content(Whitespace\" \"))))(Secondary((id \ - 2566)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2570)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2575)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2576)(content(Whitespace\" \ - \"))))(Tile((id 2602)(label(has_at_least_two_elements))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2603)(content(Whitespace\" \"))))(Tile((id 2604)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2606)(content(Whitespace\" \"))))(Tile((id 2607)(label([ \ - ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2610)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2611)(content(Whitespace\" \"))))(Tile((id 2614)(label(->))(mold((out \ - Typ)(in_())(nibs(((shape(Concave 6))(sort Typ))((shape(Concave \ - 6))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 2615)(content(Whitespace\" \"))))(Tile((id \ - 2619)(label(Bool))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2620)(content(Whitespace\" \")))))((Secondary((id \ - 2623)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2627)(label(fun ->))(mold((out Exp)(in_(Pat))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2628)(content(Whitespace\" \ - \"))))(Tile((id 2631)(label(xs))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2632)(content(Whitespace\" \")))))))))(Secondary((id \ - 2636)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2641)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2642)(content(Whitespace\" \ - \"))))(Tile((id 2645)(label(xs))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2646)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2647)(label(| =>))(mold((out Rul)(in_(Pat))(nibs(((shape(Concave \ - 19))(sort Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2649)(content(Whitespace\" \ - \"))))(Tile((id 2652)(label([]))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2653)(content(Whitespace\" \")))))))))(Secondary((id \ - 2656)(content(Whitespace\" \"))))(Tile((id \ - 2661)(label(false))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2662)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2663)(label(| =>))(mold((out Rul)(in_(Pat))(nibs(((shape(Concave \ - 19))(sort Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2665)(content(Whitespace\" \ - \"))))(Tile((id 2667)(label(hd))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2670)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave 6))(sort \ - Pat))((shape(Concave 6))(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2673)(label([]))(mold((out Pat)(in_())(nibs(((shape Convex)(sort \ - Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2674)(content(Whitespace\" \")))))))))(Secondary((id \ - 2677)(content(Whitespace\" \"))))(Tile((id \ - 2682)(label(false))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2683)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2684)(label(| =>))(mold((out Rul)(in_(Pat))(nibs(((shape(Concave \ - 19))(sort Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2686)(content(Whitespace\" \ - \"))))(Tile((id 2687)(label(a))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2690)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave 6))(sort \ - Pat))((shape(Concave 6))(sort \ - Pat))))))(shards(0))(children())))(Tile((id 2691)(label(b))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2694)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave 6))(sort \ - Pat))((shape(Concave 6))(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2697)(label([]))(mold((out Pat)(in_())(nibs(((shape Convex)(sort \ - Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2698)(content(Whitespace\" \")))))))))(Secondary((id \ - 2701)(content(Whitespace\" \"))))(Tile((id \ - 2705)(label(true))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2710)(content(Whitespace\" \"))))(Secondary((id \ - 2706)(content(Whitespace\" \"))))(Secondary((id \ - 2707)(content(Whitespace\" \"))))(Secondary((id \ - 2708)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2717)(content(Whitespace\" \"))))(Secondary((id \ - 2713)(content(Whitespace\" \"))))(Secondary((id \ - 2714)(content(Whitespace\" \"))))(Secondary((id \ - 2715)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2719)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3008)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3018)(content(Comment\"# Strings #\"))))(Secondary((id \ - 2722)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2726)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2727)(content(Whitespace\" \ - \"))))(Tile((id 2739)(label(string_lits))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2740)(content(Whitespace\" \")))))((Secondary((id \ - 2743)(content(Whitespace\" \"))))(Tile((id 2757)(label(\"\\\"Hello, \ - world!\\\"\"))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2760)(content(Whitespace\" \")))))))))(Secondary((id \ - 2762)(content(Whitespace\" \"))))(Secondary((id \ - 2764)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2768)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 2769)(content(Whitespace\" \ - \"))))(Tile((id 2785)(label(string_equality))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2786)(content(Whitespace\" \")))))((Secondary((id \ - 2789)(content(Whitespace\" \"))))(Tile((id \ - 2800)(label(string_lits))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2801)(content(Whitespace\" \"))))(Tile((id \ - 2805)(label($==))(mold((out Exp)(in_())(nibs(((shape(Concave 8))(sort \ - Exp))((shape(Concave 8))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2806)(content(Whitespace\" \"))))(Tile((id 2820)(label(\"\\\"Hello, \ - world!\\\"\"))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2823)(content(Whitespace\" \")))))))))(Secondary((id \ - 2825)(content(Whitespace\" \"))))(Secondary((id \ - 3019)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3409)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3466)(content(Comment\"# Non-empty holes are the red dotted boxes \ - around errors #\"))))(Secondary((id \ - 3467)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3519)(content(Comment\"# (you can still run programs with non-empty \ - holes) #\"))))(Secondary((id \ - 3520)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 3524)(label(let = in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape \ - Convex)(sort Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ - 2))(children(((Secondary((id 3525)(content(Whitespace\" \ - \"))))(Tile((id 3540)(label(non_empty_hole))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 3541)(content(Whitespace\" \"))))(Tile((id 3542)(label(:))(mold((out \ - Pat)(in_())(nibs(((shape(Concave 11))(sort Pat))((shape(Concave \ - 11))(sort Typ))))))(shards(0))(children())))(Secondary((id \ - 3544)(content(Whitespace\" \"))))(Tile((id \ - 3547)(label(Int))(mold((out Typ)(in_())(nibs(((shape Convex)(sort \ - Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 3548)(content(Whitespace\" \")))))((Secondary((id \ - 3551)(content(Whitespace\" \"))))(Tile((id \ - 3555)(label(true))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 3558)(content(Whitespace\" \")))))))))(Secondary((id \ - 3560)(content(Whitespace\" \"))))(Secondary((id \ - 3562)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3563)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 3564)(label(2))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ - Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 3565)(content(Whitespace\" \"))))(Tile((id 3566)(label(+))(mold((out \ - Exp)(in_())(nibs(((shape(Concave 5))(sort Exp))((shape(Concave \ - 5))(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 3568)(content(Whitespace\" \"))))(Tile((id 3569)(label(2))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2827)(content(Whitespace\"\\226\\143\\142\")))))))(ancestors())))(caret \ - Outer))"; - backup_text = - "# Hazel Language Quick Reference #\n\n\ - # Empty holes stand for missing expressions, patterns, or types #\n\ - let empty_hole = in\n\n\ - # Integers #\n\ - let int_lits : Int = 1 in\n\ - let negation = -1 in\n\ - let arithmetic = 1*2 + 8/4 in\n\ - let int_comparison = (10 == 10, 1 < 2, 2 <= 3, 3 > 2, 2 >= 1) in\n\n\ - # Floating Point Numbers #\n\ - let float_lits : Float = 1.5 in\n\ - let float_artih = 1. *. 2. +. 8. /. 4. in\n\ - let float_comparison = (10. ==. 10., 1. <. 2., 2. <=. 3., 3. >. 2., \ - 2. >=. 1.) in\n\n\ - # Booleans #\n\ - let booleans : (Bool, Bool) = (true, false) in\n\ - let conditionals =\n\ - let (x, y) = (2 + 2, 3 + 3) in\n\ - if y > x then 1 \n\ - else 2 \n\ - in\n\n\ - # Tuples #\n\ - let tuples : (Int, Bool, (Bool, Int)) = (1, true, (false, 3)) in\n\ - let (a, b, (c, d)) = tuples in\n\n\ - # Functions #\n\ - let y : (Int, Int, Int) -> Int =\n\ - fun (m, x, b) -> m * x + b \n\ - in\n\n\ - # Recursive Functions (arrow type annotation required) #\n\ - let double_recursively : Int -> Int =\n\ - fun n ->\n\ - if n == 0 then 0 \n\ - else double_recursively(n - 1) + 2 \n\ - in\n\n\ - # Lists #\n\ - let empty_list : [Int] = [] in\n\ - let non_empty_list : [Int] = 1::2::3::[] in\n\ - let list_literals : [Int] = [1, 2, 3] in\n\ - let length : [Int] -> Int =\n\ - fun xs ->\n\ - case xs\n\ - | [] => 0\n\ - | hd::tl => 1 + length(tl) \n\ - end \n\ - in\n\ - let has_at_least_two_elements : [Int] -> Bool =\n\ - fun xs ->\n\ - case xs\n\ - | [] => false\n\ - | hd::[] => false\n\ - | a::b::[] => true \n\ - end \n\ - in\n\n\ - # Strings #\n\ - let string_lits = \"Hello, world!\" in \n\ - let string_equality = string_lits $== \"Hello, world!\" in \n\n\ - # Non-empty holes are the red dotted boxes around errors #\n\ - # (you can still run programs with non-empty holes) #\n\ - let non_empty_hole : Int = true in \n\n\ - 2 + 2\n"; - } ) diff --git a/src/haz3lweb/Log.re b/src/haz3lweb/Log.re index 1fb6aee273..8663b4dc8f 100644 --- a/src/haz3lweb/Log.re +++ b/src/haz3lweb/Log.re @@ -20,14 +20,16 @@ let is_action_logged: UpdateAction.t => bool = | InitImportAll(_) | InitImportScratchpad(_) | UpdateResult(_) - | DebugAction(_) => false + | DebugAction(_) + | ExportPersistentData => false | ResetCurrentEditor | Set(_) | FinishImportAll(_) | FinishImportScratchpad(_) | ResetSlide - | ToggleMode - | SwitchSlide(_) + | SetMode(_) + | SwitchScratchSlide(_) + | SwitchExampleSlide(_) | SwitchEditor(_) | PerformAction(_) | FailedInput(_) @@ -39,7 +41,7 @@ let is_action_logged: UpdateAction.t => bool = | MoveToNextHole(_) | UpdateLangDocMessages(_) => true; -let storage_key = "LOG_" ++ SchoolSettings.log_key; +let storage_key = "LOG_" ++ ExerciseSettings.log_key; let max_log_string_length = 4_750_000; // based on 5MB limit on localstore in browser module Entry = { diff --git a/src/haz3lweb/Main.re b/src/haz3lweb/Main.re index 6f0106220b..6816daad60 100644 --- a/src/haz3lweb/Main.re +++ b/src/haz3lweb/Main.re @@ -160,9 +160,7 @@ let fragment = let initial_model = { switch (fragment) { | "debug" => Model.debug - | _ => - let model = Update.load_model(Model.blank); - model; + | _ => Model.load(Model.blank) }; }; diff --git a/src/haz3lweb/Model.re b/src/haz3lweb/Model.re index e291cc9b0a..598875313a 100644 --- a/src/haz3lweb/Model.re +++ b/src/haz3lweb/Model.re @@ -21,7 +21,7 @@ let cutoff = (===); let mk = editors => { editors, results: ModelResults.empty, - settings: ModelSettings.init, + settings: Init.startup.settings, // TODO: move below to 'io_state'? font_metrics: FontMetrics.init, logo_font_metrics: FontMetrics.init, @@ -33,3 +33,60 @@ let mk = editors => { let blank = mk(Editors.Scratch(0, [])); let debug = mk(Editors.DebugLoad); + +let load_editors = + (~mode: ModelSettings.mode, ~instructor_mode: bool): Editors.t => + switch (mode) { + | DebugLoad => DebugLoad + | Scratch => + let (idx, slides) = Store.Scratch.load(); + Scratch(idx, slides); + | Examples => + let (name, slides) = Store.Examples.load(); + Examples(name, slides); + | Exercise => + let (n, specs, exercise) = + Store.Exercise.load( + ~specs=ExerciseSettings.exercises, + ~instructor_mode, + ); + Exercise(n, specs, exercise); + }; + +let save_editors = (editors: Editors.t, ~instructor_mode: bool): unit => + switch (editors) { + | DebugLoad => failwith("no editors in debug load mode") + | Scratch(n, slides) => Store.Scratch.save((n, slides)) + | Examples(name, slides) => Store.Examples.save((name, slides)) + | Exercise(n, specs, exercise) => + Store.Exercise.save((n, specs, exercise), ~instructor_mode) + }; + +let load = (init_model: t): t => { + let settings = Store.Settings.load(); + let langDocMessages = Store.LangDocMessages.load(); + let editors = + load_editors( + ~mode=settings.mode, + ~instructor_mode=settings.instructor_mode, + ); + let results = + ModelResults.init( + settings.dynamics ? Editors.get_spliced_elabs(editors) : [], + ); + {...init_model, editors, settings, langDocMessages, results}; +}; + +let save = (model: t) => { + save_editors( + model.editors, + ~instructor_mode=model.settings.instructor_mode, + ); + Store.LangDocMessages.save(model.langDocMessages); + Store.Settings.save(model.settings); +}; + +let save_and_return = (model: t) => { + save(model); + Ok(model); +}; diff --git a/src/haz3lweb/ModelSettings.re b/src/haz3lweb/ModelSettings.re index 0e8841f885..d2ef576db9 100644 --- a/src/haz3lweb/ModelSettings.re +++ b/src/haz3lweb/ModelSettings.re @@ -1,5 +1,20 @@ open Sexplib.Std; +[@deriving (show({with_path: false}), sexp, yojson)] +type mode = + | DebugLoad + | Scratch + | Examples + | Exercise; + +let mode_of_string = (s: string): mode => + switch (s) { + | "Scratch" => Scratch + | "Examples" => Examples + | "Exercise" => Exercise + | _ => failwith("mode_of_string: unknown mode:" ++ s) + }; + [@deriving (show({with_path: false}), sexp, yojson)] type t = { captions: bool, @@ -10,25 +25,11 @@ type t = { context_inspector: bool, instructor_mode: bool, benchmark: bool, - mode: Editors.mode, + mode, }; -let init = { - captions: true, - secondary_icons: false, - statics: true, - dynamics: true, - async_evaluation: false, - context_inspector: false, - instructor_mode: SchoolSettings.show_instructor, - benchmark: false, - mode: Editors.Scratch, -}; - -let init_debug = {...init, mode: Editors.DebugLoad}; - let fix_instructor_mode = settings => - if (settings.instructor_mode && !SchoolSettings.show_instructor) { + if (settings.instructor_mode && !ExerciseSettings.show_instructor) { {...settings, instructor_mode: false}; } else { settings; diff --git a/src/haz3lweb/PersistentData.re b/src/haz3lweb/PersistentData.re new file mode 100644 index 0000000000..87bb55f155 --- /dev/null +++ b/src/haz3lweb/PersistentData.re @@ -0,0 +1,14 @@ +open Sexplib.Std; + +[@deriving (show({with_path: false}), sexp, yojson)] +type scratch = (int, list(ScratchSlide.persistent_state)); + +[@deriving (show({with_path: false}), sexp, yojson)] +type examples = (string, list((string, ScratchSlide.persistent_state))); + +[@deriving (show({with_path: false}), sexp, yojson)] +type t = { + settings: ModelSettings.t, + scratch, + examples, +}; diff --git a/src/haz3lweb/School.re b/src/haz3lweb/School.re deleted file mode 100644 index 30b0fc1b16..0000000000 --- a/src/haz3lweb/School.re +++ /dev/null @@ -1,11 +0,0 @@ -let exercises: list(SchoolExercise.spec) = SchoolSettings.exercises; -assert(List.length(exercises) > 0); - -let init = (~instructor_mode: bool): Editors.school => { - ( - 0, - exercises, - List.nth(exercises, 0) |> SchoolExercise.state_of_spec(~instructor_mode), - ); -}; -//TODO: make sure in the final version hidden editors are NOT PLAINTEXT STRINGS diff --git a/src/haz3lweb/SchoolSettings.re b/src/haz3lweb/SchoolSettings.re deleted file mode 100644 index d669d5887f..0000000000 --- a/src/haz3lweb/SchoolSettings.re +++ /dev/null @@ -1,2 +0,0 @@ -include SchoolSettings_base; -let show_instructor = true; diff --git a/src/haz3lweb/SchoolSettings_instructor.re b/src/haz3lweb/SchoolSettings_instructor.re deleted file mode 100644 index d669d5887f..0000000000 --- a/src/haz3lweb/SchoolSettings_instructor.re +++ /dev/null @@ -1,2 +0,0 @@ -include SchoolSettings_base; -let show_instructor = true; diff --git a/src/haz3lweb/SchoolSettings_student.re b/src/haz3lweb/SchoolSettings_student.re deleted file mode 100644 index f199a8cdc1..0000000000 --- a/src/haz3lweb/SchoolSettings_student.re +++ /dev/null @@ -1,2 +0,0 @@ -include SchoolSettings_base; -let show_instructor = false; diff --git a/src/haz3lweb/ScratchSlidesInit.re b/src/haz3lweb/ScratchSlidesInit.re deleted file mode 100644 index 16bd634cd8..0000000000 --- a/src/haz3lweb/ScratchSlidesInit.re +++ /dev/null @@ -1,25 +0,0 @@ -let slide0: ScratchSlide.persistent_state = LanguageRefSlide.slide; - -let empty: ScratchSlide.persistent_state = ( - 1, - { - zipper: "((selection((focus Left)(content())))(backpack())(relatives((siblings(()((Grout((id 0)(shape Convex))))))(ancestors())))(caret Outer))", - backup_text: "", - }, -); - -let num_empty = 7; - -let init_data = [slide0, ...List.init(num_empty, _ => empty)]; - -assert(List.length(init_data) > 0); - -let init = (): Editors.scratch => ( - 0, - init_data |> List.map(ScratchSlide.unpersist), -); - -let init_nth = n => { - let data = List.nth(init_data, n); - ScratchSlide.unpersist(data); -}; diff --git a/src/haz3lweb/LocalStorage.re b/src/haz3lweb/Store.re similarity index 65% rename from src/haz3lweb/LocalStorage.re rename to src/haz3lweb/Store.re index 549692055f..84913c9b0e 100644 --- a/src/haz3lweb/LocalStorage.re +++ b/src/haz3lweb/Store.re @@ -1,9 +1,11 @@ -open Sexplib.Std; +open Haz3lcore; // Settings serialization module Settings = { let save_settings_key: string = "SETTINGS"; + let default = Init.startup.settings; + let serialize = settings => settings |> ModelSettings.sexp_of_t |> Sexplib.Sexp.to_string; @@ -16,15 +18,15 @@ module Settings = { ) { | _ => print_endline("Could not deserialize settings."); - ModelSettings.init; + default; }; let save = (settings: ModelSettings.t): unit => JsUtil.set_localstore(save_settings_key, serialize(settings)); let init = () => { - JsUtil.set_localstore(save_settings_key, serialize(ModelSettings.init)); - ModelSettings.init; + JsUtil.set_localstore(save_settings_key, serialize(default)); + default; }; let load = (): ModelSettings.t => @@ -94,14 +96,14 @@ module Scratch = { let save_scratch_key: string = "SAVE_SCRATCH"; [@deriving (show({with_path: false}), sexp, yojson)] - type persistent = (int, list(ScratchSlide.persistent_state)); + type persistent = PersistentData.scratch; - let to_persistent = ((idx, slides): Editors.scratch): persistent => ( + let to_persistent = ((idx, slides)): persistent => ( idx, List.map(ScratchSlide.persist, slides), ); - let of_persistent = ((idx, slides): persistent): Editors.scratch => { + let of_persistent = ((idx, slides): persistent) => { (idx, List.map(ScratchSlide.unpersist, slides)); }; @@ -113,12 +115,12 @@ module Scratch = { data |> Sexplib.Sexp.of_string |> persistent_of_sexp |> of_persistent; }; - let save = (scratch: Editors.scratch): unit => { + let save = (scratch): unit => { JsUtil.set_localstore(save_scratch_key, serialize(scratch)); }; let init = () => { - let scratch = ScratchSlidesInit.init(); + let scratch = of_persistent(Init.startup.scratch); save(scratch); scratch; }; @@ -136,8 +138,63 @@ module Scratch = { let import = data => save(deserialize(data)); }; -module School = { - open SchoolExercise; +module Examples = { + let save_examples_key: string = "SAVE_EXAMPLES"; + + [@deriving (show({with_path: false}), sexp, yojson)] + type persistent = PersistentData.examples; + + let persist = ((name, (id, editor: Editor.t))) => { + (name, (id, PersistentZipper.persist(editor.state.zipper))); + }; + + let unpersist = ((name, (id, zipper))) => { + let (id, zipper) = PersistentZipper.unpersist(zipper, id); + (name, (id, Editor.init(zipper, ~read_only=false))); + }; + + let to_persistent = ((string, slides)): persistent => ( + string, + List.map(persist, slides), + ); + + let of_persistent = ((string, slides): persistent) => { + (string, List.map(unpersist, slides)); + }; + + let serialize = examples => { + examples |> to_persistent |> sexp_of_persistent |> Sexplib.Sexp.to_string; + }; + + let deserialize = data => { + data |> Sexplib.Sexp.of_string |> persistent_of_sexp |> of_persistent; + }; + + let save = (examples): unit => { + JsUtil.set_localstore(save_examples_key, serialize(examples)); + }; + + let init = () => { + let examples = of_persistent(Init.startup.examples); + save(examples); + examples; + }; + + let load = () => + switch (JsUtil.get_localstore(save_examples_key)) { + | None => init() + | Some(data) => + try(deserialize(data)) { + | _ => init() + } + }; + + let export = () => serialize(load()); + let import = data => save(deserialize(data)); +}; + +module Exercise = { + open Exercise; let cur_exercise_key = "CUR_EXERCISE"; @@ -158,29 +215,27 @@ module School = { }; let save_exercise = (exercise, ~instructor_mode) => { - let key = SchoolExercise.key_of_state(exercise); + let key = Exercise.key_of_state(exercise); let keystring = keystring_of_key(key); - let value = SchoolExercise.serialize_exercise(exercise, ~instructor_mode); + let value = Exercise.serialize_exercise(exercise, ~instructor_mode); JsUtil.set_localstore(keystring, value); }; let init_exercise = (spec, ~instructor_mode) => { - let key = SchoolExercise.key_of(spec); + let key = Exercise.key_of(spec); let keystring = keystring_of_key(key); - let exercise = SchoolExercise.state_of_spec(spec, ~instructor_mode); + let exercise = Exercise.state_of_spec(spec, ~instructor_mode); save_exercise(exercise, ~instructor_mode); JsUtil.set_localstore(cur_exercise_key, keystring); exercise; }; - let load_exercise = (key, spec, ~instructor_mode): SchoolExercise.state => { + let load_exercise = (key, spec, ~instructor_mode): Exercise.state => { let keystring = keystring_of_key(key); switch (JsUtil.get_localstore(keystring)) { | Some(data) => let exercise = - try( - SchoolExercise.deserialize_exercise(data, ~spec, ~instructor_mode) - ) { + try(Exercise.deserialize_exercise(data, ~spec, ~instructor_mode)) { | _ => init_exercise(spec, ~instructor_mode) }; JsUtil.set_localstore(cur_exercise_key, keystring); @@ -197,16 +252,23 @@ module School = { }; let init = (~instructor_mode) => { - let school = School.init(~instructor_mode); - save(school, ~instructor_mode); - school; + let exercises = { + ( + 0, + ExerciseSettings.exercises, + List.nth(ExerciseSettings.exercises, 0) + |> Exercise.state_of_spec(~instructor_mode), + ); + }; + save(exercises, ~instructor_mode); + exercises; }; - let load = (~specs, ~instructor_mode): Editors.school => { + let load = (~specs, ~instructor_mode) => { switch (JsUtil.get_localstore(cur_exercise_key)) { | Some(keystring) => let key = key_of_keystring(keystring); - switch (SchoolExercise.find_key_opt(key, specs)) { + switch (Exercise.find_key_opt(key, specs)) { | Some((n, spec)) => switch (JsUtil.get_localstore(keystring)) { | Some(data) => @@ -217,23 +279,21 @@ module School = { (n, specs, exercise); | None => // initialize exercise from spec - let exercise = SchoolExercise.state_of_spec(spec, ~instructor_mode); + let exercise = Exercise.state_of_spec(spec, ~instructor_mode); save_exercise(exercise, ~instructor_mode); (n, specs, exercise); } | None => // invalid current exercise key saved, load the first exercise let first_spec = List.nth(specs, 0); - let first_key = SchoolExercise.key_of(first_spec); + let first_key = Exercise.key_of(first_spec); (0, specs, load_exercise(first_key, first_spec, ~instructor_mode)); }; | None => init(~instructor_mode) }; }; - type school_export = SchoolExercise.school_export; - - let prep_school_export = (~specs, ~instructor_mode) => { + let prep_exercise_export = (~specs, ~instructor_mode) => { { cur_exercise: key_of_keystring( @@ -242,37 +302,37 @@ module School = { exercise_data: specs |> List.map(spec => { - let key = SchoolExercise.key_of(spec); + let key = Exercise.key_of(spec); let exercise = load_exercise(key, spec, ~instructor_mode) - |> SchoolExercise.persistent_state_of_state(~instructor_mode); + |> Exercise.persistent_state_of_state(~instructor_mode); (key, exercise); }), }; }; - let serialize_school_export = (~specs, ~instructor_mode) => { - prep_school_export(~specs, ~instructor_mode) - |> sexp_of_school_export + let serialize_exercise_export = (~specs, ~instructor_mode) => { + prep_exercise_export(~specs, ~instructor_mode) + |> sexp_of_exercise_export |> Sexplib.Sexp.to_string; }; let export = (~specs, ~instructor_mode) => { - serialize_school_export(~specs, ~instructor_mode); + serialize_exercise_export(~specs, ~instructor_mode); }; let import = (data, ~specs, ~instructor_mode) => { - let school_export = data |> deserialize_school_export; - save_exercise_key(school_export.cur_exercise); - school_export.exercise_data + let exercise_export = data |> deserialize_exercise_export; + save_exercise_key(exercise_export.cur_exercise); + exercise_export.exercise_data |> List.iter(((key, persistent_state)) => { - let spec = SchoolExercise.find_key_opt(key, specs); + let spec = Exercise.find_key_opt(key, specs); switch (spec) { | None => print_endline("Warning: saved key does not correspond to exercise") | Some((_, spec)) => save_exercise( - SchoolExercise.unpersist_state( + Exercise.unpersist_state( persistent_state, ~spec, ~instructor_mode, diff --git a/src/haz3lweb/Update.re b/src/haz3lweb/Update.re index ce12036075..9dad74a51b 100644 --- a/src/haz3lweb/Update.re +++ b/src/haz3lweb/Update.re @@ -2,127 +2,72 @@ open Haz3lcore; include UpdateAction; // to prevent circularity -let save_editors = (model: Model.t): unit => - switch (model.editors) { - | DebugLoad => failwith("no editors in debug load mode") - | Scratch(n, slides) => LocalStorage.Scratch.save((n, slides)) - | School(n, specs, exercise) => - LocalStorage.School.save( - (n, specs, exercise), - ~instructor_mode=model.settings.instructor_mode, - ) - }; - -let update_settings = (a: settings_action, model: Model.t): Model.t => { - let settings = model.settings; - let model = - switch (a) { - | Statics => - /* NOTE: dynamics depends on statics, so if dynamics is on and - we're turning statics off, turn dynamics off as well */ - { - ...model, - settings: { - ...settings, - statics: !settings.statics, - dynamics: !settings.statics && settings.dynamics, - }, - } - | Dynamics => { - ...model, - settings: { - ...settings, - dynamics: !settings.dynamics, - }, - } - | Benchmark => { - ...model, - settings: { - ...settings, - benchmark: !settings.benchmark, - }, - } - | Captions => { - ...model, - settings: { - ...settings, - captions: !settings.captions, - }, - } - | SecondaryIcons => { - ...model, - settings: { - ...settings, - secondary_icons: !settings.secondary_icons, - }, - } - | ContextInspector => { - ...model, - settings: { - ...settings, - context_inspector: !settings.context_inspector, - }, - } - | InstructorMode => - let new_mode = !settings.instructor_mode; - { - ...model, - editors: Editors.set_instructor_mode(model.editors, new_mode), - settings: { - ...settings, - instructor_mode: !settings.instructor_mode, - }, - }; - | Mode(mode) => { - ...model, - settings: { - ...settings, - mode, - }, - } - }; - LocalStorage.Settings.save(model.settings); - save_editors(model); - model; -}; - -let load_model = (model: Model.t): Model.t => { - let settings = LocalStorage.Settings.load(); - let langDocMessages = LocalStorage.LangDocMessages.load(); - let model = {...model, settings, langDocMessages}; - let model = - switch (model.settings.mode) { - | DebugLoad => model - | Scratch => - let (idx, slides) = LocalStorage.Scratch.load(); - {...model, editors: Scratch(idx, slides)}; - | School => - let instructor_mode = model.settings.instructor_mode; - let specs = School.exercises; - let (n, specs, exercise) = - LocalStorage.School.load(~specs, ~instructor_mode); - {...model, editors: School(n, specs, exercise)}; +let update_settings = + (a: settings_action, {settings, _} as model: Model.t): Model.t => + switch (a) { + | Statics => + /* NOTE: dynamics depends on statics, so if dynamics is on and + we're turning statics off, turn dynamics off as well */ + { + ...model, + settings: { + ...settings, + statics: !settings.statics, + dynamics: !settings.statics && settings.dynamics, + }, + } + | Dynamics => { + ...model, + settings: { + ...settings, + dynamics: !settings.dynamics, + }, + } + | Benchmark => { + ...model, + settings: { + ...settings, + benchmark: !settings.benchmark, + }, + } + | Captions => { + ...model, + settings: { + ...settings, + captions: !settings.captions, + }, + } + | SecondaryIcons => { + ...model, + settings: { + ...settings, + secondary_icons: !settings.secondary_icons, + }, + } + | ContextInspector => { + ...model, + settings: { + ...settings, + context_inspector: !settings.context_inspector, + }, + } + | InstructorMode => + let new_mode = !settings.instructor_mode; + { + ...model, + editors: Editors.set_instructor_mode(model.editors, new_mode), + settings: { + ...settings, + instructor_mode: !settings.instructor_mode, + }, }; - { - ...model, - results: - ModelResults.init( - model.settings.dynamics - ? Editors.get_spliced_elabs(model.editors) : [], - ), - }; -}; - -let load_default_editor = (model: Model.t): Model.t => - switch (model.editors) { - | DebugLoad => model - | Scratch(_) => - let (idx, editors) = LocalStorage.Scratch.init(); - {...model, editors: Scratch(idx, editors)}; - | School(_) => - let instructor_mode = model.settings.instructor_mode; - let (n, specs, exercise) = LocalStorage.School.init(~instructor_mode); - {...model, editors: School(n, specs, exercise)}; + | Mode(mode) => { + ...model, + settings: { + ...settings, + mode, + }, + } }; let reevaluate_post_update = @@ -156,7 +101,8 @@ let reevaluate_post_update = | InitImportScratchpad(_) | FailedInput(_) | UpdateLangDocMessages(_) - | DebugAction(_) => false + | DebugAction(_) + | ExportPersistentData => false // may not be necessary on all of these // TODO review and prune | ResetCurrentEditor @@ -165,8 +111,9 @@ let reevaluate_post_update = | FinishImportScratchpad(_) | ResetSlide | SwitchEditor(_) - | SwitchSlide(_) - | ToggleMode + | SwitchScratchSlide(_) + | SwitchExampleSlide(_) + | SetMode(_) | Cut | Paste(_) | Undo @@ -218,18 +165,70 @@ let perform_action = }; }; +let switch_scratch_slide = + (editors: Editors.t, ~instructor_mode, idx: int): option(Editors.t) => + switch (editors) { + | DebugLoad + | Examples(_) => None + | Scratch(n, _) when n == idx => None + | Scratch(_, slides) when idx >= List.length(slides) => None + | Scratch(_, slides) => Some(Scratch(idx, slides)) + | Exercise(_, specs, _) when idx >= List.length(specs) => None + | Exercise(_, specs, _) => + let spec = List.nth(specs, idx); + let key = Exercise.key_of(spec); + let exercise = Store.Exercise.load_exercise(key, spec, ~instructor_mode); + Some(Exercise(idx, specs, exercise)); + }; + +let switch_exercise_editor = + (editors: Editors.t, ~pos, ~instructor_mode): option(Editors.t) => + switch (editors) { + | DebugLoad + | Examples(_) + | Scratch(_) => None + | Exercise(m, specs, exercise) => + let exercise = Exercise.switch_editor(~pos, instructor_mode, ~exercise); + Store.Exercise.save_exercise(exercise, ~instructor_mode); + Some(Exercise(m, specs, exercise)); + }; + +/* This action saves a file which serializes all current editor + settings, including the states of all Scratch and Example slides. + This saved file can directly replace Haz3lweb/Init.ml, allowing + you to make your current state the default startup state. + + This does NOT save any Exercises mode state or any langdocs + state. The latter is intentional as we don't want to persist + this between users. The former is a TODO, currently difficult + due to the more complex architecture of Exercises. */ +let export_persistent_data = () => { + let data: PersistentData.t = { + examples: Store.Examples.load() |> Store.Examples.to_persistent, + scratch: Store.Scratch.load() |> Store.Scratch.to_persistent, + settings: Store.Settings.load(), + }; + let contents = + "let startup : PersistentData.t = " ++ PersistentData.show(data); + JsUtil.download_string_file( + ~filename="Init.ml", + ~content_type="text/plain", + ~contents, + ); + print_endline("INFO: Persistent data exported to Init.ml"); +}; + let apply = (model: Model.t, update: t, state: State.t, ~schedule_action) : Result.t(Model.t) => { let m: Result.t(Model.t) = switch (update) { - | Set(s_action) => Ok(update_settings(s_action, model)) + | Set(s_action) => + Model.save_and_return(update_settings(s_action, model)) | UpdateDoubleTap(double_tap) => Ok({...model, double_tap}) | Mousedown => Ok({...model, mousedown: true}) | Mouseup => Ok({...model, mousedown: false}) - | Save => - save_editors(model); - Ok(model); + | Save => Model.save_and_return(model) | InitImportAll(file) => JsUtil.read_file(file, data => schedule_action(FinishImportAll(data))); Ok(model); @@ -237,9 +236,8 @@ let apply = switch (data) { | None => Ok(model) | Some(data) => - let specs = School.exercises; - Export.import_all(data, ~specs); - Ok(load_model(model)); + Export.import_all(data, ~specs=ExerciseSettings.exercises); + Ok(Model.load(model)); } | InitImportScratchpad(file) => JsUtil.read_file(file, data => @@ -247,87 +245,37 @@ let apply = ); Ok(model); | FinishImportScratchpad(data) => - switch (model.editors) { - | DebugLoad => failwith("impossible") - | School(_) => failwith("impossible") - | Scratch(idx, slides) => - switch (data) { - | None => Ok(model) - | Some(data) => - let state = ScratchSlide.import(data); - let slides = Util.ListUtil.put_nth(idx, state, slides); - LocalStorage.Scratch.save((idx, slides)); - - Ok({...model, editors: Scratch(idx, slides)}); - } - } - | ResetSlide => - let model = - switch (model.editors) { - | DebugLoad => failwith("impossible") - | Scratch(n, slides) => - let slides = - Util.ListUtil.put_nth(n, ScratchSlidesInit.init_nth(n), slides); - {...model, editors: Scratch(n, slides)}; - | School(n, specs, _) => - let instructor_mode = model.settings.instructor_mode; - { - ...model, - editors: - School( - n, - specs, - List.nth(specs, n) - |> SchoolExercise.state_of_spec(~instructor_mode), - ), - }; - }; - save_editors(model); + let editors = Editors.import_current(model.editors, data); + Model.save_and_return({...model, editors}); + | ExportPersistentData => + export_persistent_data(); Ok(model); - | SwitchSlide(n) => - switch (model.editors) { - | DebugLoad => failwith("impossible") - | Scratch(m, _) when m == n => Error(FailedToSwitch) - | Scratch(_, slides) => - switch (n < List.length(slides)) { - | false => Error(FailedToSwitch) - | true => - LocalStorage.Scratch.save((n, slides)); - Ok({...model, editors: Scratch(n, slides)}); - } - | School(_, specs, _) => - switch (n < List.length(specs)) { - | false => Error(FailedToSwitch) - | true => - let instructor_mode = model.settings.instructor_mode; - let spec = List.nth(specs, n); - let key = SchoolExercise.key_of(spec); - let exercise = - LocalStorage.School.load_exercise(key, spec, ~instructor_mode); - Ok({...model, editors: School(n, specs, exercise)}); - } + | ResetSlide => + let instructor_mode = model.settings.instructor_mode; + let editors = Editors.reset_current(model.editors, ~instructor_mode); + Model.save_and_return({...model, editors}); + | SwitchScratchSlide(n) => + let instructor_mode = model.settings.instructor_mode; + switch (switch_scratch_slide(model.editors, ~instructor_mode, n)) { + | None => Error(FailedToSwitch) + | Some(editors) => Model.save_and_return({...model, editors}) + }; + | SwitchExampleSlide(name) => + switch (Editors.switch_example_slide(model.editors, name)) { + | None => Error(FailedToSwitch) + | Some(editors) => Model.save_and_return({...model, editors}) } | SwitchEditor(pos) => - switch (model.editors) { - | DebugLoad => failwith("impossible") - | Scratch(_) => Error(FailedToSwitch) // one editor per scratch - | School(m, specs, exercise) => - let exercise = - SchoolExercise.switch_editor( - ~pos, - model.settings.instructor_mode, - ~exercise, - ); - LocalStorage.School.save_exercise( - exercise, - ~instructor_mode=model.settings.instructor_mode, - ); - Ok({...model, editors: School(m, specs, exercise)}); - } - | ToggleMode => - let new_mode = Editors.rotate_mode(model.editors); - let model = update_settings(Mode(new_mode), model); - Ok(load_model(model)); + let instructor_mode = model.settings.instructor_mode; + switch (switch_exercise_editor(model.editors, ~pos, ~instructor_mode)) { + | None => Error(FailedToSwitch) + | Some(editors) => Model.save_and_return({...model, editors}) + }; + | SetMode(mode) => + let model = update_settings(Mode(mode), model); + /* NOTE: Need to reload model for editors to load */ + Model.save(model); + Ok(Model.load(model)); | SetShowBackpackTargets(b) => Ok({...model, show_backpack_targets: b}) | SetFontMetrics(font_metrics) => Ok({...model, font_metrics}) | SetLogoFontMetrics(logo_font_metrics) => @@ -406,8 +354,7 @@ let apply = | UpdateLangDocMessages(u) => let langDocMessages = LangDocMessages.set_update(model.langDocMessages, u); - LocalStorage.LangDocMessages.save(langDocMessages); - Ok({...model, langDocMessages}); + Model.save_and_return({...model, langDocMessages}); | UpdateResult(key, res) => /* If error, print a message. */ switch (res) { diff --git a/src/haz3lweb/UpdateAction.re b/src/haz3lweb/UpdateAction.re index 29cc3b33ff..7385833900 100644 --- a/src/haz3lweb/UpdateAction.re +++ b/src/haz3lweb/UpdateAction.re @@ -11,7 +11,7 @@ type settings_action = | Benchmark | ContextInspector | InstructorMode - | Mode(Editors.mode); + | Mode(ModelSettings.mode); [@deriving (show({with_path: false}), sexp, yojson)] type t = @@ -23,11 +23,13 @@ type t = | FinishImportAll(option(string)) | InitImportScratchpad([@opaque] Js_of_ocaml.Js.t(Js_of_ocaml.File.file)) | FinishImportScratchpad(option(string)) + | ExportPersistentData | ResetSlide | Save - | ToggleMode - | SwitchSlide(int) - | SwitchEditor(SchoolExercise.pos) + | SetMode(ModelSettings.mode) + | SwitchScratchSlide(int) + | SwitchExampleSlide(string) + | SwitchEditor(Exercise.pos) | SetFontMetrics(FontMetrics.t) | SetLogoFontMetrics(FontMetrics.t) | PerformAction(Action.t) diff --git a/src/haz3lweb/exercises/BlankTemplate.ml b/src/haz3lweb/exercises/BlankTemplate.ml index 192aeda1de..31bf1fe0b6 100644 --- a/src/haz3lweb/exercises/BlankTemplate.ml +++ b/src/haz3lweb/exercises/BlankTemplate.ml @@ -5,7 +5,7 @@ *) let exercise = - SchoolExercise.blank_spec ~title:"Recursive Fibonacci" + Exercise.blank_spec ~title:"Recursive Fibonacci" ~module_name:"Ex_RecursiveFibonacci" (* make sure your file is named .ml *) ~point_distribution: diff --git a/src/haz3lweb/exercises/Ex_OddlyRecursive.ml b/src/haz3lweb/exercises/Ex_OddlyRecursive.ml index 5441acad00..4d9aec53f7 100644 --- a/src/haz3lweb/exercises/Ex_OddlyRecursive.ml +++ b/src/haz3lweb/exercises/Ex_OddlyRecursive.ml @@ -1,6 +1,6 @@ let prompt = Ex_OddlyRecursive_prompt.prompt -let exercise : SchoolExercise.spec = +let exercise : Exercise.spec = { next_id = 5134; title = "Oddly Recursive"; diff --git a/src/haz3lweb/exercises/Ex_RecursiveFibonacci.ml b/src/haz3lweb/exercises/Ex_RecursiveFibonacci.ml index e1e9afa755..3ef6d6163f 100644 --- a/src/haz3lweb/exercises/Ex_RecursiveFibonacci.ml +++ b/src/haz3lweb/exercises/Ex_RecursiveFibonacci.ml @@ -1,6 +1,6 @@ let prompt = Ex_RecursiveFibonacci_prompt.prompt -let exercise : SchoolExercise.spec = +let exercise : Exercise.spec = { next_id = 813; title = "Recursive Fibonacci"; diff --git a/src/haz3lweb/view/BackpackView.re b/src/haz3lweb/view/BackpackView.re index bf7349e658..b2ced49b00 100644 --- a/src/haz3lweb/view/BackpackView.re +++ b/src/haz3lweb/view/BackpackView.re @@ -13,7 +13,7 @@ let backpack_sel_view = module Text = Code.Text({ let map = Measured.of_segment(content); - let settings = ModelSettings.init; + let settings = Init.startup.settings; }); // TODO(andrew): Maybe use init sort at caret to prime this div( diff --git a/src/haz3lweb/view/Cell.re b/src/haz3lweb/view/Cell.re index 05facc8846..8813021061 100644 --- a/src/haz3lweb/view/Cell.re +++ b/src/haz3lweb/view/Cell.re @@ -274,7 +274,7 @@ let editor_view = ~selected: bool, ~caption: option(Node.t)=?, ~code_id: string, - ~info_map: Statics.map, + ~info_map: Statics.Map.t, ~test_results: option(Interface.test_results), ~footer: option(Node.t), ~color_highlighting: option(ColorSteps.colorMap), @@ -339,7 +339,7 @@ let editor_with_result_view = ~selected: bool, ~caption: option(Node.t)=?, ~code_id: string, - ~info_map: Statics.map, + ~info_map: Statics.Map.t, ~result: ModelResult.simple, editor: Editor.t, ) => { diff --git a/src/haz3lweb/view/CtxInspector.re b/src/haz3lweb/view/CtxInspector.re index 36fa463408..24ee5af2ff 100644 --- a/src/haz3lweb/view/CtxInspector.re +++ b/src/haz3lweb/view/CtxInspector.re @@ -2,66 +2,70 @@ open Virtual_dom.Vdom; open Node; open Util.Web; -let context_entry_view = (~inject, entry: Haz3lcore.Ctx.entry): Node.t => - div( - ~attr= - Attr.many([ - clss(["context-entry"]), - Attr.on_click(_ => - inject( - UpdateAction.PerformAction( - Jump(TileId(Haz3lcore.Ctx.get_id(entry))), - ), - ) - ), - ]), - switch (entry) { - | VarEntry({name, typ, _}) => [text(name), text(":"), Type.view(typ)] - | TVarEntry({name, kind, _}) => [ - text("type "), - text(name), - text("::"), +let jump_to = entry => + UpdateAction.PerformAction(Jump(TileId(Haz3lcore.Ctx.get_id(entry)))); + +let context_entry_view = (~inject, entry: Haz3lcore.Ctx.entry): Node.t => { + let div_name = + div( + ~attr= + Attr.many([ + clss(["name"]), + Attr.on_click(_ => inject(jump_to(entry))), + ]), + ); + switch (entry) { + | VarEntry({name, typ, _}) + | ConstructorEntry({name, typ, _}) => + div_c( + "context-entry", + [ + div_name([text(name)]), + div(~attr=clss(["seperator"]), [text(":")]), + Type.view(typ), + ], + ) + | TVarEntry({name, kind, _}) => + div_c( + "context-entry", + [ + div_name([Type.alias_view(name)]), + div(~attr=clss(["seperator"]), [text("::")]), Kind.view(kind), - ] - }, - ); + ], + ) + }; +}; -let ctxc = "context-entries"; +let div_ctx = div(~attr=clss(["context-entries"])); -let exp_ctx_view = (~inject, ctx: Haz3lcore.Ctx.t): Node.t => { - let ctx = ctx |> Haz3lcore.Ctx.filter_duplicates; - div( - ~attr=clss([ctxc, "exp"]), - List.map(context_entry_view(~inject), List.rev(ctx)), +let ctx_view = (~inject, ctx: Haz3lcore.Ctx.t): Node.t => + div_ctx( + List.map( + context_entry_view(~inject), + ctx |> Haz3lcore.Ctx.filter_duplicates |> List.rev, + ), ); -}; -let pat_ctx_view = (~inject, ctx: Haz3lcore.Ctx.t): Node.t => { - let ctx = ctx |> Haz3lcore.Ctx.filter_duplicates; - div( - ~attr=clss([ctxc, "pat"]), - List.map(context_entry_view(~inject), List.rev(ctx)), - ); -}; - -let ctx_sorts_view = (~inject, ci: Haz3lcore.Statics.t): Node.t => { - switch (ci) { - | Invalid(_) => div(~attr=clss([ctxc, "invalid"]), [text("")]) - | InfoExp({ctx, _}) => exp_ctx_view(~inject, ctx) - | InfoPat({ctx, _}) => pat_ctx_view(~inject, ctx) - | InfoTyp(_) => div(~attr=clss([ctxc, "typ"]), []) - | InfoRul(_) => div(~attr=clss([ctxc, "rul"]), []) - }; -}; +let ctx_sorts_view = (~inject, ci: Haz3lcore.Statics.Info.t) => + Haz3lcore.Info.ctx_of(ci) + |> Haz3lcore.Ctx.filter_duplicates + |> List.rev + |> List.map(context_entry_view(~inject)); let inspector_view = - (~inject, ~settings: ModelSettings.t, _id: int, ci: Haz3lcore.Statics.t) + ( + ~inject, + ~settings: ModelSettings.t, + _id: int, + ci: Haz3lcore.Statics.Info.t, + ) : Node.t => { let clss = clss( ["context-inspector"] @ (settings.context_inspector ? ["visible"] : []), ); - div(~attr=clss, [ctx_sorts_view(~inject, ci)]); + div(~attr=clss, ctx_sorts_view(~inject, ci)); }; let view = @@ -69,7 +73,7 @@ let view = ~inject, ~settings: ModelSettings.t, index': option(int), - info_map: Haz3lcore.Statics.map, + info_map: Haz3lcore.Statics.Map.t, ) => { let (index, ci) = switch (index') { diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index ee67d1f695..2221760aa1 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -2,274 +2,249 @@ open Virtual_dom.Vdom; open Node; open Util.Web; open Util; +open Haz3lcore; -let cls_str = (ci: Haz3lcore.Statics.t): string => - switch (ci) { - | Invalid(msg) => Haz3lcore.TermBase.show_parse_flag(msg) - | InfoExp({cls, _}) => Haz3lcore.Term.UExp.show_cls(cls) - | InfoPat({cls, _}) => Haz3lcore.Term.UPat.show_cls(cls) - | InfoTyp({cls, _}) => Haz3lcore.Term.UTyp.show_cls(cls) - | InfoRul({cls, _}) => Haz3lcore.Term.URul.show_cls(cls) - }; +let errc = "error"; +let okc = "ok"; +let div_err = div(~attr=clss([errc])); +let div_ok = div(~attr=clss([okc])); + +let lang_doc_toggle = (~inject, ~show_lang_doc) => { + let tooltip = "Toggle language documentation"; + let toggle_landocs = _ => + Virtual_dom.Vdom.Effect.Many([ + inject(Update.UpdateLangDocMessages(LangDocMessages.ToggleShow)), + Virtual_dom.Vdom.Effect.Stop_propagation, + ]); + div( + ~attr=clss(["lang-doc-button"]), + [Widgets.toggle(~tooltip, "i", show_lang_doc, toggle_landocs)], + ); +}; + +let cls_view = (ci: Info.t) => + div( + ~attr=clss(["syntax-class"]), + [text(ci |> Info.cls_of |> Term.Cls.show)], + ); -let errorc = "error"; -let happyc = "happy"; -let infoc = "info"; +let term_view = (~inject, ~settings: ModelSettings.t, ~show_lang_doc, id, ci) => { + let sort = ci |> Info.sort_of |> Sort.show; + let context_menu = + div( + ~attr= + Attr.many([ + Attr.on_click(_ => inject(Update.Set(ContextInspector))), + clss(["gamma"] @ (settings.context_inspector ? ["visible"] : [])), + ]), + [text("Γ")], + ); + div( + ~attr= + clss( + ["ci-header", "ci-header-" ++ sort] + @ (Info.is_error(ci) ? [errc] : []), + ), + [ + context_menu, + CtxInspector.inspector_view(~inject, ~settings, id, ci), + div(~attr=clss(["term-tag"]), [text(sort)]), + lang_doc_toggle(~inject, ~show_lang_doc), + cls_view(ci), + ], + ); +}; -let error_view = (err: Haz3lcore.Statics.error) => +let no_type_error = (err: Info.error_no_type) => switch (err) { - | Multi => - div(~attr=clss([errorc, "err-multi"]), [text("⑂ Multi Hole")]) - | Free(Variable) => - div( - ~attr=clss([errorc, "err-free-variable"]), - [text("Variable is not bound")], - ) - | NoFun(typ) => - div( - ~attr=clss([errorc, "err-not-function"]), - [text("Not a function: "), Type.view(typ)], - ) - | Free(TypeVariable) => - div( - ~attr=clss([errorc, "err-free-variable"]), - [text("Type Variable is not bound")], - ) - | Free(Tag) => - div( - ~attr=clss([errorc, "err-free-variable"]), - [text("Constructor is not defined")], - ) - | SynInconsistentBranches(tys) => - div( - ~attr=clss([errorc, "err-inconsistent-branches"]), - [text("Expecting branches to have consistent types but got:")] - @ ListUtil.join(text(","), List.map(Type.view, tys)), - ) - | TypeInconsistent(ty_syn, ty_ana) => - div( - ~attr=clss([errorc, "err-type-inconsistent"]), - [ - text("Expecting"), - Type.view(ty_ana), - text("but found"), - Type.view(ty_syn), - ], - ) + | BadToken(token) => + switch (Form.bad_token_cls(token)) { + | BadInt => "Integer is too large or too small" + | Other => Printf.sprintf("\"%s\" isn't a valid token", token) + } + | FreeConstructor(name) => "'" ++ name ++ "' not found" }; -let happy_view = (suc: Haz3lcore.Statics.happy) => { - switch (suc) { - | SynConsistent(ty_syn) => - div( - ~attr=clss([happyc, "syn-consistent"]), - [text("has type"), Type.view(ty_syn)], - ) - | AnaConsistent(ty_ana, ty_syn, _ty_join) when ty_ana == ty_syn => - div( - ~attr=clss([happyc, "ana-consistent-equal"]), - [text("has expected type"), Type.view(ty_ana)], - ) - | AnaConsistent(ty_ana, ty_syn, _ty_join) => - div( - ~attr=clss([happyc, "ana-consistent"]), - switch (ty_syn) { - // A hack for EECS 490 A1 - | Haz3lcore.Typ.Unknown(_) => [ - text("has expected type"), - Type.view(ty_ana), - ] - | _ => [ - text("has type"), - Type.view(ty_syn), - text("which is consistent with"), - Type.view(ty_ana), - ] - }, - ) - | AnaInternalInconsistent(ty_ana, _) - | AnaExternalInconsistent(ty_ana, _) => - div( - ~attr=clss([happyc, "ana-consistent-external"]), - [ - div( - ~attr=clss(["typ-view", "atom"]), - [text("⇐"), div(~attr=clss(["typ-mod"]), [text("☆")])], - ), - Type.view(ty_ana), - ], - ) - }; -}; +let elements_noun: Term.Cls.t => string = + fun + | Exp(Match | If) => "Branches" + | Exp(ListLit) + | Pat(ListLit) => "Elements" + | _ => failwith("elements_noun: Cls doesn't have elements"); -let status_view = (err: Haz3lcore.Statics.error_status) => { +let common_err_view = (cls: Term.Cls.t, err: Info.error_common) => switch (err) { - | InHole(error) => error_view(error) - | NotInHole(happy) => happy_view(happy) + | NoType(err) => [text(no_type_error(err))] + | Inconsistent(WithArrow(typ)) => [ + Type.view(typ), + text("is inconsistent with arrow type"), + ] + | Inconsistent(Internal(tys)) => [ + text(elements_noun(cls) ++ " have inconsistent types:"), + ...ListUtil.join(text(","), List.map(Type.view, tys)), + ] + | Inconsistent(Expectation({ana, syn})) => [ + text(":"), + Type.view(syn), + text("inconsistent with expected type"), + Type.view(ana), + ] + }; + +let common_ok_view = (cls: Term.Cls.t, ok: Info.ok_pat) => { + switch (ok) { + | Syn(_) when cls == Exp(EmptyHole) => [ + text("Fillable by any expression"), + ] + | Syn(_) when cls == Pat(EmptyHole) => [text("Fillable by any pattern")] + | Ana(Consistent({ana, _})) + when cls == Exp(EmptyHole) || cls == Pat(EmptyHole) => [ + text("Expecting type"), + Type.view(ana), + ] + | Syn(syn) => [text(":"), Type.view(syn)] + | Ana(Consistent({ana, syn, _})) when ana == syn => [ + text(":"), + Type.view(syn), + text("exactly satisfies expected type"), + ] + | Ana(Consistent({ana, syn: Unknown(_) as syn, _})) => [ + text(":"), + Type.view(syn), + text("trivially satisfies expected type"), + Type.view(ana), + ] + | Ana(Consistent({ana: Unknown(_) as ana, syn, _})) => [ + text(":"), + Type.view(syn), + text("satisfies trivial expected type"), + Type.view(ana), + ] + | Ana(Consistent({ana, syn, _})) => [ + text(":"), + Type.view(syn), + text("satisfies expected type"), + Type.view(ana), + ] + | Ana(InternallyInconsistent({ana, nojoin: tys})) => + [ + text(elements_noun(cls) ++ " have inconsistent types:"), + ...ListUtil.join(text(","), List.map(Type.view, tys)), + ] + @ [text("but these satisfy expected type"), Type.view(ana)] }; }; -let term_tag = (~inject, ~show_lang_doc, is_err, sort) => { - let lang_doc = - div( - ~attr=clss(["lang-doc-button"]), - [ - Widgets.toggle( - ~tooltip="Toggle language documentation", "i", show_lang_doc, _ => - Effect.Many([ - inject(Update.UpdateLangDocMessages(LangDocMessages.ToggleShow)), - Effect.Stop_propagation, - ]) - ), - ], - ); +let typ_ok_view = (cls: Term.Cls.t, ok: Info.ok_typ) => + switch (ok) { + | Type(_) when cls == Typ(EmptyHole) => [text("Fillable by any type")] + | Type(ty) => [Type.view(ty)] + | TypeAlias(name, ty_lookup) => [ + Type.view(Var(name)), + text("is a type alias for"), + Type.view(ty_lookup), + ] + | Variant(name, _sum_ty) => [Type.view(Var(name))] + | VariantIncomplete(_sum_ty) => [text("is incomplete")] + }; - div( - ~attr= - Attr.many([ - clss(["term-tag", "term-tag-" ++ sort] @ (is_err ? [errorc] : [])), - ]), - [div(~attr=clss(["gamma"]), [text("Γ")]), text(sort), lang_doc], - ); -}; +let typ_err_view = (ok: Info.error_typ) => + switch (ok) { + | FreeTypeVariable(name) => [Type.view(Var(name)), text("not found")] + | BadToken(token) => [ + text("'" ++ token ++ "' isn't a type or type operator"), + ] + | WantConstructorFoundAp + | WantConstructorFoundType(_) => [text("Expected a constructor")] + | WantTypeFoundAp => [text("Must be part of a sum type")] + | DuplicateConstructor(name) => [ + Type.view(Var(name)), + text("already used in this sum"), + ] + }; -let view_of_info = - (~inject, ~show_lang_doc: bool, ci: Haz3lcore.Statics.t): Node.t => { - let is_err = Haz3lcore.Statics.is_error(ci); - switch (ci) { - | Invalid(msg) => - div( - ~attr=clss([infoc, "unknown"]), - [text("🚫 " ++ Haz3lcore.TermBase.show_parse_flag(msg))], - ) - | InfoExp({mode, self, _}) => - let error_status = Haz3lcore.Statics.error_status(mode, self); - div( - ~attr=clss([infoc, "exp"]), - [ - term_tag(~inject, ~show_lang_doc, is_err, "exp"), - status_view(error_status), - ], - ); - | InfoPat({mode, self, _}) => - let error_status = Haz3lcore.Statics.error_status(mode, self); - div( - ~attr=clss([infoc, "pat"]), - [ - term_tag(~inject, ~show_lang_doc, is_err, "pat"), - status_view(error_status), - ], - ); - | InfoTyp({self: Free(free_error), _}) => - div( - ~attr=clss([infoc, "typ"]), - [ - term_tag(~inject, ~show_lang_doc, is_err, "typ"), - error_view(Free(free_error)), - ], - ) - | InfoTyp({self: Just(ty), _}) => - div( - ~attr=clss([infoc, "typ"]), - [ - term_tag(~inject, ~show_lang_doc, is_err, "typ"), - text("is"), - Type.view(ty), - ], - ) - | InfoTyp({self: _, _}) => - failwith("CursorInspector: Impossible type error") - | InfoRul(_) => - div( - ~attr=clss([infoc, "rul"]), - [term_tag(~inject, ~show_lang_doc, is_err, "rul"), text("Rule")], - ) +let exp_view = (cls: Term.Cls.t, status: Info.status_exp) => + switch (status) { + | InHole(FreeVariable(name)) => + div_err([text("'" ++ name ++ "' not found")]) + | InHole(Common(error)) => div_err(common_err_view(cls, error)) + | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; -}; -let cls_view = (ci: Haz3lcore.Statics.t): Node.t => - div(~attr=clss(["syntax-class"]), [text(cls_str(ci))]); +let pat_view = (cls: Term.Cls.t, status: Info.status_pat) => + switch (status) { + | InHole(ExpectedConstructor) => div_err([text("Expected a constructor")]) + | InHole(Common(error)) => div_err(common_err_view(cls, error)) + | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) + }; -let id_view = (id): Node.t => - div(~attr=clss(["id"]), [text(string_of_int(id + 1))]); +let typ_view = (cls: Term.Cls.t, status: Info.status_typ) => + switch (status) { + | NotInHole(ok) => div_ok(typ_ok_view(cls, ok)) + | InHole(err) => div_err(typ_err_view(err)) + }; -let extra_view = (visible: bool, id: int, ci: Haz3lcore.Statics.t): Node.t => - div( - ~attr=Attr.many([clss(["extra"] @ (visible ? ["visible"] : []))]), - [id_view(id), cls_view(ci)], - ); +let tpat_view = (_: Term.Cls.t, status: Info.status_tpat) => + switch (status) { + | NotInHole(Empty) => div_ok([text("Fillable with a new type alias")]) + | NotInHole(Var(name)) => div_ok([Type.alias_view(name)]) + | InHole(NotAVar(NotCapitalized)) => + div_err([text("Must begin with a capital letter")]) + | InHole(NotAVar(_)) => div_err([text("Expected a type alias")]) + | InHole(ShadowsType(name)) when Form.is_base_typ(name) => + div_err([text("Can't shadow base type"), Type.view(Var(name))]) + | InHole(ShadowsType(name)) => + div_err([text("Can't shadow existing alias"), Type.view(Var(name))]) + }; -let toggle_context_and_print_ci = (~inject: Update.t => 'a, ci, _) => { - print_endline(Haz3lcore.Statics.show(ci)); +let view_of_info = + (~inject, ~settings, ~show_lang_doc: bool, id, ci: Statics.Info.t): Node.t => { + let wrapper = status_view => + div( + ~attr=clss(["info"]), + [term_view(~inject, ~settings, ~show_lang_doc, id, ci), status_view], + ); switch (ci) { - | InfoPat({mode, self, _}) - | InfoExp({mode, self, _}) => - Haz3lcore.Statics.error_status(mode, self) - |> Haz3lcore.Statics.show_error_status - |> print_endline - | _ => () + | InfoExp({cls, status, _}) => wrapper(exp_view(cls, status)) + | InfoPat({cls, status, _}) => wrapper(pat_view(cls, status)) + | InfoTyp({cls, status, _}) => wrapper(typ_view(cls, status)) + | InfoTPat({cls, status, _}) => wrapper(tpat_view(cls, status)) }; - inject(Set(ContextInspector)); }; -let inspector_view = - ( - ~inject, - ~settings: ModelSettings.t, - ~show_lang_doc: bool, - id: int, - ci: Haz3lcore.Statics.t, - ) - : Node.t => +let inspector_view = (~inject, ~settings, ~show_lang_doc, id, ci): Node.t => div( - ~attr= - Attr.many([ - clss( - ["cursor-inspector"] - @ [Haz3lcore.Statics.is_error(ci) ? errorc : happyc], - ), - Attr.on_click(toggle_context_and_print_ci(~inject, ci)), - ]), - [ - extra_view(settings.context_inspector, id, ci), - view_of_info(~inject, ~show_lang_doc, ci), - CtxInspector.inspector_view(~inject, ~settings, id, ci), - ], + ~attr=clss(["cursor-inspector"] @ [Info.is_error(ci) ? errc : okc]), + [view_of_info(~inject, ~settings, ~show_lang_doc, id, ci)], ); let view = ( ~inject, - ~settings, + ~settings: ModelSettings.t, ~show_lang_doc: bool, - zipper: Haz3lcore.Zipper.t, - info_map: Haz3lcore.Statics.map, + zipper: Zipper.t, + info_map: Statics.Map.t, ) => { - let backpack = zipper.backpack; - if (List.length(backpack) > 0) { - div([]); - } else { - let index = Haz3lcore.Indicated.index(zipper); - - switch (index) { - | Some(index) => - switch (Haz3lcore.Id.Map.find_opt(index, info_map)) { - | Some(ci) => - inspector_view(~inject, ~settings, ~show_lang_doc, index, ci) - | None => - div( - ~attr=clss(["cursor-inspector"]), - [div(~attr=clss(["icon"]), [Icons.magnify]), text("")], - ) - } - | None => + let bar_view = div(~attr=Attr.id("bottom-bar")); + let err_view = err => + bar_view([ div( - ~attr=clss(["cursor-inspector"]), - [ - div(~attr=clss(["icon"]), [Icons.magnify]), - text("No Indicated Index"), - ], - ) - }; + ~attr=clss(["cursor-inspector", "no-info"]), + [div(~attr=clss(["icon"]), [Icons.magnify]), text(err)], + ), + ]); + switch (zipper.backpack, Indicated.index(zipper)) { + | ([_, ..._], _) => err_view("No information while backpack in use") + | (_, None) => err_view("No cursor in program") + | (_, Some(id)) => + switch (Id.Map.find_opt(id, info_map)) { + | None => err_view("Whitespace or Comment") + | Some(ci) => + bar_view([ + inspector_view(~inject, ~settings, ~show_lang_doc, id, ci), + div(~attr=clss(["id"]), [text(string_of_int(id + 1))]), + ]) + } }; }; diff --git a/src/haz3lweb/view/DebugMode.re b/src/haz3lweb/view/DebugMode.re index f8ed4cf2bc..ee01231c44 100644 --- a/src/haz3lweb/view/DebugMode.re +++ b/src/haz3lweb/view/DebugMode.re @@ -20,7 +20,7 @@ let view = (~inject) => { btn( ~inject, "clear local storage (LOSE ALL DATA!)", - UpdateAction.DebugAction(ClearLocalStorage), + UpdateAction.DebugAction(ClearStore), ), ]) ); diff --git a/src/haz3lweb/view/Deco.re b/src/haz3lweb/view/Deco.re index 5cd7bc9959..6125d4ce7d 100644 --- a/src/haz3lweb/view/Deco.re +++ b/src/haz3lweb/view/Deco.re @@ -10,7 +10,7 @@ module Deco = let show_backpack_targets: bool; let terms: TermMap.t; let term_ranges: TermRanges.t; - let info_map: Statics.map; + let info_map: Statics.Map.t; let tiles: TileMap.t; }, ) => { @@ -277,7 +277,7 @@ module Deco = let is_err = (id: Id.t) => switch (Id.Map.find_opt(id, M.info_map)) { | None => false - | Some(info) => Statics.is_error(info) + | Some(info) => Info.is_error(info) }; let is_rep = (id: Id.t) => switch (Id.Map.find_opt(id, M.terms)) { diff --git a/src/haz3lweb/view/EditorModeView.re b/src/haz3lweb/view/EditorModeView.re new file mode 100644 index 0000000000..3fe4a306f8 --- /dev/null +++ b/src/haz3lweb/view/EditorModeView.re @@ -0,0 +1,83 @@ +open Virtual_dom.Vdom; +open Node; +open Widgets; + +let option_view = (name, n) => + option( + ~attr=n == name ? Attr.create("selected", "selected") : Attr.many([]), + [text(n)], + ); + +let mode_menu = (~inject, ~mode: ModelSettings.mode) => + div( + ~attr=Attr.many([Attr.class_("mode-name"), Attr.title("Toggle Mode")]), + [ + select( + ~attr= + Attr.on_change((_, name) => + inject(Update.SetMode(ModelSettings.mode_of_string(name))) + ), + List.map( + option_view(ModelSettings.show_mode(mode)), + ["Scratch", "Examples", "Exercise"], + ), + ), + ], + ); + +let slide_select = (~inject, ~cur_slide, ~num_slides) => { + let next_ed = (cur_slide + 1) mod num_slides; + let prev_ed = Util.IntUtil.modulo(cur_slide - 1, num_slides); + [ + button(Icons.back, _ => inject(Update.SwitchScratchSlide(prev_ed))), + text(Printf.sprintf("%d / %d", cur_slide + 1, num_slides)), + button(Icons.forward, _ => inject(Update.SwitchScratchSlide(next_ed))), + ]; +}; + +let scratch_view = (~inject, ~cur_slide, ~slides) => + [mode_menu(~inject, ~mode=Scratch)] + @ slide_select(~inject, ~cur_slide, ~num_slides=List.length(slides)); + +let examples_view = (~inject, ~name, ~editors) => [ + mode_menu(~inject, ~mode=Examples), + select( + ~attr= + Attr.on_change((_, name) => inject(Update.SwitchExampleSlide(name))), + List.map(option_view(name), List.map(fst, editors)), + ), +]; + +let instructor_toggle = (~inject, ~instructor_mode) => + ExerciseSettings.show_instructor + ? [ + toggle("🎓", ~tooltip="Toggle Instructor Mode", instructor_mode, _ => + inject(Update.Set(InstructorMode)) + ), + ] + : []; + +let exercises_view = (~inject, ~cur_slide, ~specs, ~instructor_mode) => { + [mode_menu(~inject, ~mode=Exercise)] + @ instructor_toggle(~inject, ~instructor_mode) + @ slide_select(~inject, ~cur_slide, ~num_slides=List.length(specs)); +}; + +let view = + ( + ~inject: Update.t => 'a, + ~editors: Editors.t, + ~settings as {instructor_mode, _}: ModelSettings.t, + ) + : Node.t => { + let contents = + switch (editors) { + | DebugLoad => [] + | Scratch(cur_slide, slides) => + scratch_view(~inject, ~cur_slide, ~slides) + | Examples(name, editors) => examples_view(~inject, ~name, ~editors) + | Exercise(cur_slide, specs, _) => + exercises_view(~cur_slide, ~specs, ~inject, ~instructor_mode) + }; + div(~attr=Attr.id("editor-mode"), contents); +}; diff --git a/src/haz3lweb/view/SchoolMode.re b/src/haz3lweb/view/ExerciseMode.re similarity index 88% rename from src/haz3lweb/view/SchoolMode.re rename to src/haz3lweb/view/ExerciseMode.re index 04b44a9433..5cbeb84542 100644 --- a/src/haz3lweb/view/SchoolMode.re +++ b/src/haz3lweb/view/ExerciseMode.re @@ -3,26 +3,26 @@ open Virtual_dom.Vdom; open Node; type t = { - exercise: SchoolExercise.state, + exercise: Exercise.state, results: option(ModelResults.t), settings: ModelSettings.t, langDocMessages: LangDocMessages.t, - stitched_dynamics: SchoolExercise.stitched(SchoolExercise.DynamicsItem.t), + stitched_dynamics: Exercise.stitched(Exercise.DynamicsItem.t), grading_report: Grading.GradingReport.t, }; let mk = ( - ~exercise: SchoolExercise.state, + ~exercise: Exercise.state, ~results: option(ModelResults.t), ~settings, ~langDocMessages, ) : t => { - let SchoolExercise.{eds, _} = exercise; + let Exercise.{eds, _} = exercise; let stitched_dynamics = Util.TimeUtil.measure_time("stitch_dynamics", true, () => - SchoolExercise.stitch_dynamic(exercise, results) + Exercise.stitch_dynamic(exercise, results) ); let grading_report = Grading.GradingReport.mk(eds, ~stitched_dynamics); @@ -61,8 +61,8 @@ let view = grading_report, langDocMessages, } = self; - let SchoolExercise.{pos, eds} = exercise; - let SchoolExercise.{ + let Exercise.{pos, eds} = exercise; + let Exercise.{ test_validation, user_impl, user_tests, @@ -72,7 +72,7 @@ let view = hidden_tests: _, } = stitched_dynamics; let (focal_zipper, focal_info_map) = - SchoolExercise.focus(exercise, stitched_dynamics); + Exercise.focus(exercise, stitched_dynamics); let color_highlighting: option(ColorSteps.colorMap) = if (langDocMessages.highlight && langDocMessages.show) { @@ -171,7 +171,7 @@ let view = switch (specific_ctx) { | None => Node.div([text("No context available")]) // TODO show exercise configuration error | Some(specific_ctx) => - CtxInspector.exp_ctx_view(~inject, specific_ctx) + CtxInspector.ctx_view(~inject, specific_ctx) }; }; }; @@ -218,8 +218,8 @@ let view = ( i, ( - SchoolExercise.{impl, _}, - SchoolExercise.DynamicsItem.{info_map, simple_result, _}, + Exercise.{impl, _}, + Exercise.DynamicsItem.{info_map, simple_result, _}, ), ) => { InstructorOnly( @@ -326,7 +326,7 @@ let view = ), ); - let ci_view = + let bottom_bar = settings.statics ? [ CursorInspector.view( @@ -338,7 +338,17 @@ let view = ), ] : []; - + let sidebar = + langDocMessages.show && settings.statics + ? LangDoc.view( + ~inject, + ~font_metrics, + ~settings, + ~doc=langDocMessages, + Indicated.index(focal_zipper), + focal_info_map, + ) + : div([]); [ div( ~attr=Attr.id("main"), @@ -362,36 +372,23 @@ let view = hidden_tests_view, impl_grading_view, ], - ) - @ ( - langDocMessages.show && settings.statics - ? [ - LangDoc.view( - ~inject, - ~font_metrics, - ~settings, - ~doc=langDocMessages, - Indicated.index(focal_zipper), - focal_info_map, - ), - ] - : [] - ), + ), ), ], ), - div(~attr=Attr.class_("bottom-bar"), ci_view), - ]; // TODO lang doc visibility tied to ci visibility (is this desired?) + sidebar, + ] + @ bottom_bar; }; let toolbar_buttons = (~inject, editors: Editors.t, ~settings: ModelSettings.t) => { - let (_idx, _specs, exercise): Editors.school = + let (_idx, _specs, exercise): Editors.exercises = switch (editors) { - | School(idx, specs, exercise) => (idx, specs, exercise) + | Exercise(idx, specs, exercise) => (idx, specs, exercise) | _ => assert(false) }; - let SchoolExercise.{pos: _, eds} = exercise; + let Exercise.{pos: _, eds} = exercise; let reset_button = Widgets.button( @@ -420,8 +417,7 @@ let toolbar_buttons = let module_name = eds.module_name; let filename = eds.module_name ++ ".ml"; let content_type = "text/plain"; - let contents = - SchoolExercise.export_module(module_name, exercise); + let contents = Exercise.export_module(module_name, exercise); JsUtil.download_string_file( ~filename, ~content_type, @@ -445,10 +441,7 @@ let toolbar_buttons = let filename = eds.module_name ++ ".ml"; let content_type = "text/plain"; let contents = - SchoolExercise.export_transitionary_module( - module_name, - exercise, - ); + Exercise.export_transitionary_module(module_name, exercise); JsUtil.download_string_file( ~filename, ~content_type, @@ -472,7 +465,7 @@ let toolbar_buttons = let filename = eds.module_name ++ "_grading.ml"; let content_type = "text/plain"; let contents = - SchoolExercise.export_grading_module(module_name, exercise); + Exercise.export_grading_module(module_name, exercise); JsUtil.download_string_file( ~filename, ~content_type, diff --git a/src/haz3lweb/view/Icons.re b/src/haz3lweb/view/Icons.re index 915191db30..543690448f 100644 --- a/src/haz3lweb/view/Icons.re +++ b/src/haz3lweb/view/Icons.re @@ -136,3 +136,19 @@ let magnify = "M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z", ], ); + +let chest = + simple_icon( + ~view="0 0 100 125", + [ + "M56,54v-4c0-1.1,0.9-2,2-2s2,0.9,2,2v4c0,1.1-0.9,2-2,2S56,55.1,56,54z M94,28v12v36c0,3.3-2.7,6-6,6H12c-3.3,0-6-2.7-6-6 V40V28c0-5.5,4.5-10,10-10h68C89.5,18,94,22.5,94,28z M84,22H24c1.3,1.7,2,3.7,2,6v10h64V28C90,24.7,87.3,22,84,22z M10,38h12V28 c0-3.3-2.7-6-6-6s-6,2.7-6,6V38z M12,78h10V42H10v34C10,77.1,10.9,78,12,78z M90,42H26v36h62c1.1,0,2-0.9,2-2V42z", + ], + ); + +let sprout = + simple_icon( + ~view="0 0 100 125", + [ + "M48.8,68.2c-2,0.8-1.6,2.2-2.1,2.5c-0.8,0.3-0.1-1-2.1-1.6c-4.5-1.4-4,4.3-6.5,4.2c-1.7-0.1-1.8-0.6-3.4-0.4 c-1.6,0.3-1.1,2.1-2.9,2.3c-1.1,0.1-0.7,1.2-2.4,1c-1.4-0.2-2,1.6-2.1,2.7c-0.1,0.8-0.3,1.6-1.6,2.3c-1.2,0.7-3.3,0.2-4.4,1.7 c-1.6,2-1.7,5.1-1.7,5.1h60.7c0,0-0.1-2.3-2.6-3.9c-0.7-0.4,0.1-0.4,0.4-2c0.1-0.6,0-1.5-0.7-2.6c-0.9-1.3-2.7-0.9-3.4-0.7 c0.2-0.9,0.2-2-1.2-2.9c-1-0.7-1.3-0.3-1.9-0.4c-0.7-0.1-0.3-0.8-1-1.2c-1.8-1.1-0.5-2.1-3.3-3.2c-1.7-0.7-2-0.6-5.6-0.6 c-1.4,0-1.7-2.3-3.6-1.8c-1.9,0.6-1.1-0.5-2.2-1.6c-0.3-0.3-0.9-0.5-1.5-0.5c-0.1-10.6-0.1-24.5,0.3-27.2c0.6-4.5,5.7-9.8,13.1-10.6 c-7,5.2-10.2,6.7-10.8,9.9c-0.6,3.2,5.1,2.5,9.6,0c4.5-2.5,12.1-14.6,12.4-19c-6.4-1.6-22,4.1-27.1,16.6C49.6,26.6,47.7,12,20.3,12 c-0.1,2.6,0.6,2.9,1.9,6.1c1.3,3.2,9.9,18.1,20.7,17.5c1.6-0.1-0.3-3.8-2.9-6.8c0,0-6.4-5.9-8.3-7.5c6.4,2.5,16.2,9.9,17,15.3 c0.5,3.5,0.4,20.2,0.2,31.7C49,68.2,48.9,68.2,48.8,68.2z", + ], + ); diff --git a/src/haz3lweb/view/Kind.re b/src/haz3lweb/view/Kind.re index 419b507c6f..f84672515c 100644 --- a/src/haz3lweb/view/Kind.re +++ b/src/haz3lweb/view/Kind.re @@ -2,16 +2,8 @@ open Virtual_dom.Vdom; open Node; open Util.Web; -// TODO: (poly) Finish the skeleton -let kind_view = (cls: string, s: string): Node.t => - div(~attr=clss(["kind-view", cls]), [text(s)]); - -// TODO: (poly) Finish the skeleton -let view = (ty: Haz3lcore.Kind.t): Node.t => - switch (ty) { - | Type => - div( - ~attr=clss(["kind-view"]), - [text("S"), kind_view("Singleton", "Singleton")], - ) +let view = (kind: Haz3lcore.Kind.t): Node.t => + switch (kind) { + | Singleton(ty) => div_c("kind-view", [Type.view(ty)]) + | Abstract => div_c("kind-view", [text("Type")]) }; diff --git a/src/haz3lweb/view/LangDoc.re b/src/haz3lweb/view/LangDoc.re index 97c88f8939..5fb3a6bdf0 100644 --- a/src/haz3lweb/view/LangDoc.re +++ b/src/haz3lweb/view/LangDoc.re @@ -250,18 +250,11 @@ let deco = let get_clss = segment => switch (List.nth(segment, 0)) { - | Base.Tile({mold, _}) => - switch (mold.out) { - | Pat => ["term-tag-pat"] - | Exp => ["term-tag-exp"] // TODO the brown on brown isn't the greatest... but okay - | Typ => ["term-tag-typ"] - | Any - | Nul - | Rul => [] - } + | Base.Tile({mold, _}) => [ + "ci-header-" ++ Sort.to_string(mold.out), + ] | _ => [] }; - let specificity_menu = Node.div( ~attr= @@ -493,7 +486,11 @@ type message_mode = | Colorings; let get_doc = - (~docs: LangDocMessages.t, info: option(Statics.t), mode: message_mode) + ( + ~docs: LangDocMessages.t, + info: option(Statics.Info.t), + mode: message_mode, + ) : (list(Node.t), (list(Node.t), ColorSteps.t), list(Node.t)) => { let default = ( [text("No syntactic form available")], @@ -556,38 +553,38 @@ let get_doc = }; }; + let basic_info = group => { + let (doc, options) = LangDocMessages.get_form_and_options(group, docs); + get_message(doc, options, group, doc.explanation.message, []); + }; + switch (info) { | Some(InfoExp({term, _})) => let rec get_message_exp = (term) : (list(Node.t), (list(Node.t), ColorSteps.t), list(Node.t)) => - switch (term) { - | TermBase.UExp.Invalid(_) => default - | EmptyHole => + switch ((term: TermBase.UExp.term)) { + | Invalid(_) => default + | EmptyHole => basic_info(LangDocMessages.empty_hole_exp_group) + | MultiHole(_) => basic_info(LangDocMessages.multi_hole_exp_group) + | TyAlias(ty_pat, ty_def, _body) => let (doc, options) = LangDocMessages.get_form_and_options( - LangDocMessages.empty_hole_exp_group, + LangDocMessages.tyalias_exp_group, docs, ); + let tpat_id = List.nth(ty_pat.ids, 0); + let def_id = List.nth(ty_def.ids, 0); get_message( doc, options, - LangDocMessages.empty_hole_exp_group, - doc.explanation.message, - [], - ); - | MultiHole(_children) => - let (doc, options) = - LangDocMessages.get_form_and_options( - LangDocMessages.multi_hole_exp_group, - docs, - ); - get_message( - doc, - options, - LangDocMessages.multi_hole_exp_group, - doc.explanation.message, - [], + LangDocMessages.tyalias_exp_group, + Printf.sprintf( + Scanf.format_from_string(doc.explanation.message, "%i%i"), + def_id, + tpat_id, + ), + LangDocMessages.tyalias_base_exp_coloring_ids(~tpat_id, ~def_id), ); | Triv => let (doc, options) = @@ -1156,19 +1153,19 @@ let get_doc = } else { basic(doc, LangDocMessages.function_ap_group, options); }; - | Tag(v) => + | Constructor(v) => let (doc, options) = LangDocMessages.get_form_and_options( - LangDocMessages.function_tag_group, + LangDocMessages.function_ctr_group, docs, ); - if (LangDocMessages.function_tag_exp.id == doc.id) { + if (LangDocMessages.function_ctr_exp.id == doc.id) { let pat_id = List.nth(pat.ids, 0); let body_id = List.nth(body.ids, 0); get_message( doc, options, - LangDocMessages.function_tag_group, + LangDocMessages.function_ctr_group, Printf.sprintf( Scanf.format_from_string(doc.explanation.message, "%i%s%i%i"), pat_id, @@ -1176,13 +1173,13 @@ let get_doc = pat_id, body_id, ), - LangDocMessages.function_tag_exp_coloring_ids( + LangDocMessages.function_ctr_exp_coloring_ids( ~pat_id, ~body_id, ), ); } else { - basic(doc, LangDocMessages.function_tag_group, options); + basic(doc, LangDocMessages.function_ctr_group, options); }; | Invalid(_) => default // Shouldn't get hit | Parens(_) => default // Shouldn't get hit? @@ -1817,20 +1814,20 @@ let get_doc = } else { basic(doc, LangDocMessages.let_ap_exp_group, options); }; - | Tag(v) => + | Constructor(v) => let (doc, options) = LangDocMessages.get_form_and_options( - LangDocMessages.let_tag_exp_group, + LangDocMessages.let_ctr_exp_group, docs, ); - if (LangDocMessages.let_tag_exp.id == doc.id) { + if (LangDocMessages.let_ctr_exp.id == doc.id) { let pat_id = List.nth(pat.ids, 0); let def_id = List.nth(def.ids, 0); let body_id = List.nth(body.ids, 0); get_message( doc, options, - LangDocMessages.let_tag_exp_group, + LangDocMessages.let_ctr_exp_group, Printf.sprintf( Scanf.format_from_string( doc.explanation.message, @@ -1842,14 +1839,14 @@ let get_doc = def_id, body_id, ), - LangDocMessages.let_tag_exp_coloring_ids( + LangDocMessages.let_ctr_exp_coloring_ids( ~pat_id, ~def_id, ~body_id, ), ); } else { - basic(doc, LangDocMessages.let_tag_exp_group, options); + basic(doc, LangDocMessages.let_ctr_exp_group, options); }; | Invalid(_) => default // Shouldn't get hit | Parens(_) => default // Shouldn't get hit? @@ -1869,7 +1866,7 @@ let get_doc = ); }; switch (x.term) { - | Tag(v) => + | Constructor(v) => let (doc, options) = LangDocMessages.get_form_and_options( LangDocMessages.conapp_exp_group, @@ -2130,16 +2127,16 @@ let get_doc = ), LangDocMessages.case_exp_coloring_ids(~scrut_id), ); - | Tag(v) => + | Constructor(v) => let (doc, options) = LangDocMessages.get_form_and_options( - LangDocMessages.tag_exp_group, + LangDocMessages.ctr_exp_group, docs, ); get_message( doc, options, - LangDocMessages.tag_exp_group, + LangDocMessages.ctr_exp_group, Printf.sprintf( Scanf.format_from_string(doc.explanation.message, "%s"), v, @@ -2464,16 +2461,16 @@ let get_doc = ), LangDocMessages.ap_pat_coloring_ids(~con_id, ~arg_id), ); - | Tag(con) => + | Constructor(con) => let (doc, options) = LangDocMessages.get_form_and_options( - LangDocMessages.tag_pat_group, + LangDocMessages.ctr_pat_group, docs, ); get_message( doc, options, - LangDocMessages.tag_pat_group, + LangDocMessages.ctr_pat_group, Printf.sprintf( Scanf.format_from_string(doc.explanation.message, "%s"), con, @@ -2504,7 +2501,7 @@ let get_doc = // Shouldn't be hit? default } - | Some(InfoTyp({term, _})) => + | Some(InfoTyp({term, cls, _})) => switch (bypass_parens_typ(term).term) { | EmptyHole => let (doc, options) = @@ -2726,6 +2723,10 @@ let get_doc = ); basic(doc, LangDocMessages.tuple_typ_group, options); }; + | Constructor(_) => + basic_info(LangDocMessages.sum_typ_nullary_constructor_def_group) + | Var(_) when cls == Typ(Constructor) => + basic_info(LangDocMessages.sum_typ_nullary_constructor_def_group) | Var(v) => let (doc, options) = LangDocMessages.get_form_and_options( @@ -2742,12 +2743,34 @@ let get_doc = ), [], ); - | Invalid(_) // Shouldn't be hit + | Sum(_) => basic_info(LangDocMessages.labelled_sum_typ_group) + | Ap(_) => basic_info(LangDocMessages.sum_typ_unary_constructor_def_group) | Parens(_) => default // Shouldn't be hit? + | Invalid(_) => default + } + | Some(InfoTPat(info)) => + switch (info.term.term) { + | Invalid(_) => default + | EmptyHole => basic_info(LangDocMessages.empty_hole_tpat_group) + | MultiHole(_) => basic_info(LangDocMessages.multi_hole_tpat_group) + | Var(v) => + let (doc, options) = + LangDocMessages.get_form_and_options( + LangDocMessages.var_typ_pat_group, + docs, + ); + get_message( + doc, + options, + LangDocMessages.var_typ_pat_group, + Printf.sprintf( + Scanf.format_from_string(doc.explanation.message, "%s"), + v, + ), + [], + ); } - | Some(InfoRul(_)) // Can't have cursor on just a rule atm - | None - | Some(Invalid(_)) => default + | None => default }; }; @@ -2758,8 +2781,8 @@ let section = (~section_clss: string, ~title: string, contents: list(Node.t)) => ); let get_color_map = - (~doc: LangDocMessages.t, index': option(int), info_map: Statics.map) => { - let info: option(Statics.t) = + (~doc: LangDocMessages.t, index': option(int), info_map: Statics.Map.t) => { + let info: option(Statics.Info.t) = switch (index') { | Some(index) => switch (Id.Map.find_opt(index, info_map)) { @@ -2779,9 +2802,9 @@ let view = ~settings: ModelSettings.t, ~doc: LangDocMessages.t, index': option(int), - info_map: Statics.map, + info_map: Statics.Map.t, ) => { - let info: option(Statics.t) = + let info: option(Statics.Info.t) = switch (index') { | Some(index) => switch (Id.Map.find_opt(index, info_map)) { @@ -2793,10 +2816,10 @@ let view = let (syn_form, (explanation, _), example) = get_doc(~docs=doc, info, MessageContent(inject, font_metrics, settings)); div( - ~attr=clss(["lang-doc"]), + ~attr=Attr.id("side-bar"), [ div( - ~attr=clss(["content"]), + ~attr=clss(["lang-doc"]), [ div( ~attr=clss(["top-bar"]), @@ -2820,7 +2843,7 @@ let view = ) ), ]), - [text("X")], + [text("✕")], ), ], ), diff --git a/src/haz3lweb/view/Page.re b/src/haz3lweb/view/Page.re index 0b0813e9dd..a3166c737e 100644 --- a/src/haz3lweb/view/Page.re +++ b/src/haz3lweb/view/Page.re @@ -5,179 +5,119 @@ open Util.Web; open Haz3lcore; open Widgets; -let next_slide = (~inject: Update.t => 'a, cur_slide, num_slides, _) => { - let next_ed = (cur_slide + 1) mod num_slides; - inject(SwitchSlide(next_ed)); -}; - let download_editor_state = (~instructor_mode) => { let data = Export.export_all(~instructor_mode); - JsUtil.download_json(SchoolSettings.filename, data); + JsUtil.download_json(ExerciseSettings.filename, data); }; - -let prev_slide = (~inject: Update.t => 'a, cur_slide, num_slides, _) => { - let prev_ed = Util.IntUtil.modulo(cur_slide - 1, num_slides); - inject(SwitchSlide(prev_ed)); -}; - -let slide_toggle_view = (~inject, ~model: Model.t, ~caption, ~control) => { - let id = Attr.id("editor-mode"); - let tooltip = Attr.title("Toggle Mode"); - let toggle_mode = Attr.on_mousedown(_ => inject(Update.ToggleMode)); - let cur_slide = Editors.cur_slide(model.editors); - let num_slides = Editors.num_slides(model.editors); - let cur_slide_text = Printf.sprintf("%d / %d", cur_slide + 1, num_slides); - div( - ~attr=id, - [ - div(~attr=Attr.many([toggle_mode, tooltip]), [text(caption)]), - button(Icons.back, prev_slide(~inject, cur_slide, num_slides)), - text(cur_slide_text), - button(Icons.forward, next_slide(~inject, cur_slide, num_slides)), - ] - @ Option.to_list(control), - ); +let menu_icon = { + let attr = + Attr.many( + Attr.[ + clss(["menu-icon"]), + href("https://hazel.org"), + title("Hazel"), + create("target", "_blank"), + ], + ); + a(~attr, [Icons.hazelnut]); }; -let editor_mode_toggle_view = (~inject: Update.t => 'a, ~model: Model.t) => { - switch (model.editors) { - | DebugLoad => failwith("impossible") - | Scratch(_) => - slide_toggle_view(~inject, ~model, ~caption="Scratch", ~control=None) - | School(_) => - let control = - if (SchoolSettings.show_instructor) { - Some( - toggle( - "🎓", - ~tooltip="Toggle Instructor Mode", - model.settings.instructor_mode, - _ => - inject(Set(InstructorMode)) - ), - ); - } else { - None; - }; - slide_toggle_view(~inject, ~model, ~caption="Exercises", ~control); - }; -}; +let history_bar = (ed: Editor.t, ~inject: Update.t => 'a) => [ + button_d( + Icons.undo, + inject(Undo), + ~disabled=!Editor.can_undo(ed), + ~tooltip="Undo", + ), + button_d( + Icons.redo, + inject(Redo), + ~disabled=!Editor.can_redo(ed), + ~tooltip="Redo", + ), +]; -let menu_icon = +let nut_menu = + ( + ~inject: Update.t => 'a, + {statics, dynamics, benchmark, instructor_mode, _}: ModelSettings.t, + ) => [ + menu_icon, div( - ~attr=clss(["menu-icon"]), + ~attr=clss(["menu"]), [ - div( - ~attr=clss(["icon", "menu-icon-inner"]), - [ - a( - ~attr= - Attr.many( - Attr.[ - href("https://hazel.org"), - title("Hazel"), - create("target", "_blank"), - ], - ), - [Icons.hazelnut], - ), - ], + toggle("τ", ~tooltip="Toggle Statics", statics, _ => + inject(Set(Statics)) ), - ], - ); + toggle("𝛿", ~tooltip="Toggle Dynamics", dynamics, _ => + inject(Set(Dynamics)) + ), + toggle("b", ~tooltip="Toggle Performance Benchmark", benchmark, _ => + inject(Set(Benchmark)) + ), + button( + Icons.export, + _ => { + download_editor_state(~instructor_mode); + Virtual_dom.Vdom.Effect.Ignore; + }, + ~tooltip="Export Submission", + ), + file_select_button( + "import-submission", + Icons.import, + file => { + switch (file) { + | None => Virtual_dom.Vdom.Effect.Ignore + | Some(file) => inject(InitImportAll(file)) + } + }, + ~tooltip="Import Submission", + ), + button( + Icons.eye, + _ => inject(Set(SecondaryIcons)), + ~tooltip="Toggle Visible Secondary", + ), + link( + Icons.github, + "https://github.com/hazelgrove/hazel", + ~tooltip="Hazel on GitHub", + ), + ] + @ ( + instructor_mode + ? [ + button( + Icons.sprout, + _ => inject(ExportPersistentData), + ~tooltip="Export Persistent Data", + ), + ] + : [] + ), + ), +]; let top_bar_view = ( ~inject: Update.t => 'a, ~toolbar_buttons: list(Node.t), - ~top_right: option(Node.t)=?, - model: Model.t, - ) => { - let ed = Editors.get_editor(model.editors); - let can_undo = Editor.can_undo(ed); - let can_redo = Editor.can_redo(ed); - let top_left_bar = - div( - ~attr=Attr.id("top-left-bar"), - [ - menu_icon, - div( - ~attr=clss(["menu"]), - [ - toggle("τ", ~tooltip="Toggle Statics", model.settings.statics, _ => - inject(Set(Statics)) - ), - toggle( - "𝛿", ~tooltip="Toggle Dynamics", model.settings.dynamics, _ => - inject(Set(Dynamics)) - ), - toggle( - "b", - ~tooltip="Toggle Performance Benchmark", - model.settings.benchmark, - _ => - inject(Set(Benchmark)) - ), - button( - Icons.export, - _ => { - download_editor_state( - ~instructor_mode=model.settings.instructor_mode, - ); - Virtual_dom.Vdom.Effect.Ignore; - }, - ~tooltip="Export Submission", - ), - file_select_button( - "import-submission", - Icons.import, - file => { - switch (file) { - | None => Virtual_dom.Vdom.Effect.Ignore - | Some(file) => inject(InitImportAll(file)) - } - }, - ~tooltip="Import Submission", - ), - button( - Icons.eye, - _ => inject(Set(SecondaryIcons)), - ~tooltip="Toggle Visible Secondary", - ), - link( - Icons.github, - "https://github.com/hazelgrove/hazel", - ~tooltip="Hazel on GitHub", - ), - ], - ), - button_d( - Icons.undo, - inject(Undo), - ~disabled=!can_undo, - ~tooltip="Undo", - ), - button_d( - Icons.redo, - inject(Redo), - ~disabled=!can_redo, - ~tooltip="Redo", - ), - editor_mode_toggle_view(~inject, ~model), - ] - @ toolbar_buttons, - ); - let top_right_bar = - div(~attr=Attr.id("top-right-bar"), Option.to_list(top_right)); + ~model as {editors, settings, _}: Model.t, + ) => div( ~attr=Attr.id("top-bar"), - [div(~attr=Attr.id("top-bar-content"), [top_left_bar, top_right_bar])], + nut_menu(~inject, settings) + @ [div(~attr=Attr.id("title"), [text("hazel")])] + @ [EditorModeView.view(~inject, ~settings, ~editors)] + @ history_bar(Editors.get_editor(editors), ~inject) + @ toolbar_buttons, ); -}; -let main_ui_view = +let exercises_view = ( ~inject, + ~exercise, { editors, font_metrics, @@ -189,70 +129,54 @@ let main_ui_view = _, } as model: Model.t, ) => { - switch (editors) { - | DebugLoad => [DebugMode.view(~inject)] - | Scratch(idx, slides) => - let toolbar_buttons = - ScratchMode.toolbar_buttons(~inject, List.nth(slides, idx)); - let top_bar_view = top_bar_view(~inject, ~toolbar_buttons, model); - let result_key = ScratchSlide.scratch_key; - let editor = Editors.get_editor(editors); - let result = - settings.dynamics - ? ModelResult.get_simple(ModelResults.lookup(results, result_key)) - : None; + let exercise_mode = + ExerciseMode.mk( + ~settings, + ~exercise, + ~results=settings.dynamics ? Some(results) : None, + ~langDocMessages, + ); + let toolbar_buttons = + ExerciseMode.toolbar_buttons(~inject, ~settings, editors) + @ [ + Grading.GradingReport.view_overall_score(exercise_mode.grading_report), + ]; + [top_bar_view(~inject, ~model, ~toolbar_buttons)] + @ ExerciseMode.view( + ~inject, + ~font_metrics, + ~mousedown, + ~show_backpack_targets, + exercise_mode, + ); +}; - [top_bar_view] - @ ScratchMode.view( - ~inject, - ~font_metrics, - ~mousedown, - ~show_backpack_targets, - ~settings, - ~langDocMessages, - ~editor, - ~result, - ); - | School(_, _, exercise) => - let toolbar_buttons = - SchoolMode.toolbar_buttons(~inject, ~settings, editors); - let results = settings.dynamics ? Some(results) : None; - let school_mode = - SchoolMode.mk(~settings, ~exercise, ~results, ~langDocMessages); - let grading_report = school_mode.grading_report; - let overall_score = - Grading.GradingReport.view_overall_score(grading_report); - let top_bar_view = - top_bar_view( - ~inject, - model, - ~toolbar_buttons, - ~top_right=overall_score, - ); +let slide_view = (~inject, ~model, slide_state) => { + let toolbar_buttons = ScratchMode.toolbar_buttons(~inject, slide_state); + [top_bar_view(~inject, ~toolbar_buttons, ~model)] + @ ScratchMode.view(~inject, ~model); +}; - [top_bar_view] - @ SchoolMode.view( - ~inject, - ~font_metrics, - ~mousedown, - ~show_backpack_targets, - school_mode, - ); +let editors_view = (~inject, model: Model.t) => { + switch (model.editors) { + | DebugLoad => [DebugMode.view(~inject)] + | Scratch(slide_idx, slides) => + slide_view(~inject, ~model, List.nth(slides, slide_idx)) + | Examples(name, slides) => + slide_view(~inject, ~model, List.assoc(name, slides)) + | Exercise(_, _, exercise) => exercises_view(~inject, ~exercise, model) }; }; -let page_id = "page"; - let get_selection = (model: Model.t): string => model.editors |> Editors.get_editor |> Printer.to_string_selection; -let view = (~inject, ~handlers, model: Model.t) => { - let main_ui = main_ui_view(~inject, model); +let view = (~inject, ~handlers, model: Model.t) => div( ~attr= Attr.many( Attr.[ - id(page_id), + id("page"), // safety handler in case mousedown overlay doesn't catch it on_mouseup(_ => inject(Update.Mouseup)), on_blur(_ => { @@ -286,6 +210,5 @@ let view = (~inject, ~handlers, model: Model.t) => { DecUtil.filters, JsUtil.clipboard_shim, ] - @ main_ui, + @ editors_view(~inject, model), ); -}; diff --git a/src/haz3lweb/view/ScratchMode.re b/src/haz3lweb/view/ScratchMode.re index b658082e24..b0edee347d 100644 --- a/src/haz3lweb/view/ScratchMode.re +++ b/src/haz3lweb/view/ScratchMode.re @@ -8,19 +8,29 @@ type state = (Id.t, Editor.t); let view = ( ~inject, - ~font_metrics, - ~show_backpack_targets, - ~mousedown, - ~editor: Editor.t, - ~settings: ModelSettings.t, - ~langDocMessages: LangDocMessages.t, - ~result: ModelResult.simple, + ~model as + { + editors, + font_metrics, + show_backpack_targets, + settings, + mousedown, + langDocMessages, + results, + _, + }: Model.t, ) => { + let editor = Editors.get_editor(editors); let zipper = editor.state.zipper; let unselected = Zipper.unselect_and_zip(zipper); let (term, _) = MakeTerm.go(unselected); let info_map = Statics.mk_map(term); - + let result = + settings.dynamics + ? ModelResult.get_simple( + ModelResults.lookup(results, ScratchSlide.scratch_key), + ) + : None; let color_highlighting: option(ColorSteps.colorMap) = if (langDocMessages.highlight && langDocMessages.show) { Some( @@ -50,7 +60,7 @@ let view = ~result, editor, ); - let ci_view = + let bottom_bar = settings.statics ? [ CursorInspector.view( @@ -62,28 +72,26 @@ let view = ), ] : []; - let bottom_bar = div(~attr=Attr.class_("bottom-bar"), ci_view); - let right_panel = + let sidebar = langDocMessages.show && settings.statics - ? [ - LangDoc.view( + ? LangDoc.view( ~inject, ~font_metrics, ~settings, ~doc=langDocMessages, Indicated.index(zipper), info_map, - ), - ] - : []; + ) + : div([]); [ div( ~attr=Attr.id("main"), - [div(~attr=clss(["editor", "single"]), [editor_view] @ right_panel)], + [div(~attr=clss(["editor", "single"]), [editor_view])], ), - bottom_bar, - ]; + sidebar, + ] + @ bottom_bar; }; let download_slide_state = state => { @@ -125,9 +133,9 @@ let toolbar_buttons = (~inject, state: ScratchSlide.state) => { ~tooltip="Import Scratchpad", ); - // for pasting into files like LanguageRefSlide.ml (note .ml extension) + // for pasting into files like SerializedExamples.ml (note .ml extension) let export_init_button = - SchoolSettings.show_instructor + ExerciseSettings.show_instructor ? Some( Widgets.button( Icons.export, diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index dc42c37f76..12678ea17f 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -5,13 +5,18 @@ open Util.Web; let ty_view = (cls: string, s: string): Node.t => div(~attr=clss(["typ-view", cls]), [text(s)]); +let alias_view = (s: string): Node.t => + div(~attr=clss(["typ-alias-view"]), [text(s)]); + let prov_view: Haz3lcore.Typ.type_provenance => Node.t = fun | Internal => div([]) + | Free(name) => + div(~attr=clss(["typ-mod", "free-type-var"]), [text(name)]) | TypeHole => div(~attr=clss(["typ-mod", "type-hole"]), [text("𝜏")]) | SynSwitch => div(~attr=clss(["typ-mod", "syn-switch"]), [text("⇒")]); -let rec view = (ty: Haz3lcore.Typ.t): Node.t => +let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => //TODO: parens on ops when ambiguous switch (ty) { | Unknown(prov) => @@ -24,19 +29,24 @@ let rec view = (ty: Haz3lcore.Typ.t): Node.t => | String => ty_view("String", "String") | Bool => ty_view("Bool", "Bool") | Var(name) => ty_view("Var", name) + | Rec(x, t) => + div( + ~attr=clss(["typ-view", "Rec"]), + [text("Rec " ++ x ++ ". "), view_ty(t)], + ) | List(t) => div( ~attr=clss(["typ-view", "atom", "List"]), - [text("["), view(t), text("]")], + [text("["), view_ty(t), text("]")], ) | Arrow(t1, t2) => div( ~attr=clss(["typ-view", "Arrow"]), - [view(t1), text("->"), view(t2)], + [view_ty(t1), text(" -> "), view_ty(t2)], ) | Prod([]) => div(~attr=clss(["typ-view", "Prod"]), [text("()")]) | Prod([_]) => - div(~attr=clss(["typ-view", "Prod"]), [text("BadProduct")]) + div(~attr=clss(["typ-view", "Prod"]), [text("Singleton Product")]) | Prod([t0, ...ts]) => div( ~attr=clss(["typ-view", "atom", "Prod"]), @@ -44,12 +54,30 @@ let rec view = (ty: Haz3lcore.Typ.t): Node.t => text("("), div( ~attr=clss(["typ-view", "Prod"]), - [view(t0)] - @ (List.map(t => [text(","), view(t)], ts) |> List.flatten), + [view_ty(t0)] + @ (List.map(t => [text(", "), view_ty(t)], ts) |> List.flatten), ), text(")"), ], ) - | Sum(t1, t2) => - div(~attr=clss(["typ-view", "Sum"]), [view(t1), text("+"), view(t2)]) + | Sum(ts) => + div( + ~attr=clss(["typ-view", "Sum"]), + switch (ts) { + | [] => [text("Nullary Sum")] + | [t0] => [text("+")] @ ctr_view(t0) + | [t0, ...ts] => + let ts_views = + List.map(t => [text(" + ")] @ ctr_view(t), ts) |> List.flatten; + ctr_view(t0) @ ts_views; + }, + ) + } +and ctr_view = ((ctr, typ)) => + switch (typ) { + | None => [text(ctr)] + | Some(typ) => [text(ctr ++ "("), view_ty(typ), text(")")] }; + +let view = (ty: Haz3lcore.Typ.t): Node.t => + div_c("typ-wrapper", [view_ty(ty)]); diff --git a/src/haz3lweb/view/dec/PieceDec.re b/src/haz3lweb/view/dec/PieceDec.re index e6a6a74f69..43c90344e7 100644 --- a/src/haz3lweb/view/dec/PieceDec.re +++ b/src/haz3lweb/view/dec/PieceDec.re @@ -141,13 +141,27 @@ let chunky_shard = ) => { let (nib_l, origin) = { let (id, index) = i; - let (_, mold, shards) = List.find(((id', _, _)) => id' == id, tiles); - (fst(Mold.nib_shapes(~index, mold)), List.assoc(index, shards).origin); + let (_, mold, shards) = + switch (List.find_opt(((id', _, _)) => id' == id, tiles)) { + | Some(x) => x + | None => failwith("chunky_shard 1") + }; + ( + fst(Mold.nib_shapes(~index, mold)), + ListUtil.assoc_err(index, shards, "chunky_shard").origin, + ); }; let (nib_r, last) = { let (id, index) = j; - let (_, mold, shards) = List.find(((id', _, _)) => id' == id, tiles); - (snd(Mold.nib_shapes(~index, mold)), List.assoc(index, shards).last); + let (_, mold, shards) = + switch (List.find_opt(((id', _, _)) => id' == id, tiles)) { + | Some(x) => x + | None => failwith("chunky_shard 2") + }; + ( + snd(Mold.nib_shapes(~index, mold)), + ListUtil.assoc_err(index, shards, "chunky_shard").last, + ); }; let indent_col = Measured.Rows.find(origin.row, rows).indent; let max_col = diff --git a/src/haz3lweb/view/dhcode/DHCode.re b/src/haz3lweb/view/dhcode/DHCode.re index ed242dc337..394cff2f51 100644 --- a/src/haz3lweb/view/dhcode/DHCode.re +++ b/src/haz3lweb/view/dhcode/DHCode.re @@ -55,22 +55,28 @@ let view_of_layout = ds, ) | CastDecoration => ([with_cls("CastDecoration", txt)], ds) + | OperationError(InvalidIntOfString) => ( + [with_cls("OperationError", txt)], + ds, + ) + | OperationError(InvalidFloatOfString) => ( + [with_cls("OperationError", txt)], + ds, + ) | OperationError(DivideByZero) => ( - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], ds, ) | OperationError(NegativeExponent) => ( - [with_cls("NegativeExponent", txt)], + [with_cls("OperationError", txt)], ds, ) | OperationError(OutOfFuel) => ( - //TODO: custom class - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], ds, ) | OperationError(InvalidProjection) => ( - //TODO: custom class - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], ds, ) | VarHole(_) => ([with_cls("InVarHole", txt)], ds) @@ -190,21 +196,27 @@ let view_of_layout_tylr = ) | CastDecoration => ([with_cls("CastDecoration", txt)], ds) | OperationError(DivideByZero) => ( - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], + ds, + ) + | OperationError(InvalidIntOfString) => ( + [with_cls("OperationError", txt)], + ds, + ) + | OperationError(InvalidFloatOfString) => ( + [with_cls("OperationError", txt)], ds, ) | OperationError(NegativeExponent) => ( - [with_cls("NegativeExponent", txt)], + [with_cls("OperationError", txt)], ds, ) | OperationError(OutOfFuel) => ( - //TODO: custom class - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], ds, ) | OperationError(InvalidProjection) => ( - //TODO: custom class - [with_cls("DivideByZero", txt)], + [with_cls("OperationError", txt)], ds, ) | VarHole(_) => ([with_cls("InVarHole", txt)], ds) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index b648a0a2ed..ad54cad1a3 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -51,10 +51,9 @@ let rec precedence = (~show_casts: bool, d: DHExp.t) => { | FloatLit(_) | StringLit(_) | ListLit(_) - | Inj(_) | Prj(_) | EmptyHole(_) - | Tag(_) + | Constructor(_) | FailedCast(_) | InvalidOperation(_) | Fun(_) @@ -207,31 +206,23 @@ let rec mk = | InconsistentBranches(u, i, Case(dscrut, drs, _)) => go_case(dscrut, drs) |> annot(DHAnnot.InconsistentBranches((u, i))) | BoundVar(x) => text(x) - | Tag(name) => DHDoc_common.mk_TagLit(name) + | Constructor(name) => DHDoc_common.mk_ConstructorLit(name) | BoolLit(b) => DHDoc_common.mk_BoolLit(b) | IntLit(n) => DHDoc_common.mk_IntLit(n) | FloatLit(f) => DHDoc_common.mk_FloatLit(f) - | StringLit(s) => DHDoc_common.mk_StringLit(s) + | StringLit(s) => DHDoc_common.mk_StringLit("\"" ++ s ++ "\"") | TestLit(_) => Doc.text(ExpandingKeyword.to_string(Test)) | Sequence(d1, d2) => let (doc1, doc2) = (go'(d1), go'(d2)); DHDoc_common.mk_Sequence(mk_cast(doc1), mk_cast(doc2)); - | ListLit(_, _, StandardErrStatus(_), _, d_list) => + | ListLit(_, _, _, d_list) => let ol = d_list |> List.map(go') |> List.map(mk_cast); DHDoc_common.mk_ListLit(ol); - | ListLit(u, i, InconsistentBranches(_, _), _, d_list) => - let ol = d_list |> List.map(go') |> List.map(mk_cast); - DHDoc_common.mk_ListLit(ol) - |> annot(DHAnnot.InconsistentBranches((u, i))); - | Inj(_, inj_side, d) => - let child = (~enforce_inline) => mk_cast(go(~enforce_inline, d)); - DHDoc_common.mk_Inj( - inj_side, - child |> DHDoc_common.pad_child(~enforce_inline), - ); | Ap(d1, d2) => - let (doc1, doc2) = - mk_left_associative_operands(DHDoc_common.precedence_Ap, d1, d2); + let (doc1, doc2) = ( + go'(~parenthesize=precedence(d1) > DHDoc_common.precedence_Ap, d1), + go'(~parenthesize=false, d2), + ); DHDoc_common.mk_Ap(mk_cast(doc1), mk_cast(doc2)); | ApBuiltin(ident, args) => switch (args) { diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re index 832cc58407..c27aa21b07 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re @@ -8,14 +8,14 @@ let precedence = (dp: DHPat.t) => | Wild | ExpandingKeyword(_) | InvalidText(_) + | BadConstructor(_) | Var(_) | IntLit(_) | FloatLit(_) | BoolLit(_) | StringLit(_) - | Inj(_) | ListLit(_) - | Tag(_) => DHDoc_common.precedence_const + | Constructor(_) => DHDoc_common.precedence_const | Tuple(_) => DHDoc_common.precedence_Comma | Cons(_) => DHDoc_common.precedence_Cons | Ap(_) => DHDoc_common.precedence_Ap @@ -40,18 +40,14 @@ let rec mk = | ExpandingKeyword(u, i, k) => DHDoc_common.mk_ExpandingKeyword((u, i), k) | InvalidText(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i)) + | BadConstructor(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i)) | Var(x) => Doc.text(x) | Wild => DHDoc_common.Delim.wild - | Tag(name) => DHDoc_common.mk_TagLit(name) + | Constructor(name) => DHDoc_common.mk_ConstructorLit(name) | IntLit(n) => DHDoc_common.mk_IntLit(n) | FloatLit(f) => DHDoc_common.mk_FloatLit(f) | BoolLit(b) => DHDoc_common.mk_BoolLit(b) | StringLit(s) => DHDoc_common.mk_StringLit(s) - | Inj(inj_side, dp) => - DHDoc_common.mk_Inj( - inj_side, - mk(dp) |> DHDoc_common.pad_child(~enforce_inline), - ) | ListLit(_, d_list) => let ol = List.map(mk', d_list); DHDoc_common.mk_ListLit(ol); diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re new file mode 100644 index 0000000000..1923f9c821 --- /dev/null +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re @@ -0,0 +1,114 @@ +open Util; +open Haz3lcore; + +module Doc = Pretty.Doc; + +[@deriving sexp] +type t = Doc.t(DHAnnot.t); + +type formattable_child = (~enforce_inline: bool) => t; + +let precedence_const = DHDoc_common.precedence_const; +let precedence_Ap = DHDoc_common.precedence_Ap; +let precedence_Times = DHDoc_common.precedence_Times; +let precedence_Divide = DHDoc_common.precedence_Divide; +let precedence_Plus = DHDoc_common.precedence_Plus; +let precedence_Minus = DHDoc_common.precedence_Minus; +let precedence_Cons = DHDoc_common.precedence_Cons; +let precedence_Equals = DHDoc_common.precedence_Equals; +let precedence_LessThan = DHDoc_common.precedence_LessThan; +let precedence_GreaterThan = DHDoc_common.precedence_GreaterThan; +let precedence_And = DHDoc_common.precedence_And; +let precedence_Or = DHDoc_common.precedence_Or; +let precedence_Comma = DHDoc_common.precedence_Comma; +let precedence_max = DHDoc_common.precedence_max; + +let pad_child = + ( + ~inline_padding as (l, r)=(Doc.empty(), Doc.empty()), + ~enforce_inline: bool, + child: formattable_child, + ) + : t => { + let inline_choice = Doc.hcats([l, child(~enforce_inline=true), r]); + let para_choice = + Doc.( + hcats([ + linebreak(), + indent_and_align(child(~enforce_inline=false)), + linebreak(), + ]) + ); + enforce_inline ? inline_choice : Doc.choice(inline_choice, para_choice); +}; + +module Delim = { + let mk = (delim_text: string): t => + Doc.text(delim_text) |> Doc.annot(DHAnnot.Delim); + + let empty_hole = ((u, i): HoleInstance.t): t => { + let lbl = + StringUtil.cat([string_of_int(u + 1), ":", string_of_int(i + 1)]); + Doc.text(lbl) + |> Doc.annot(DHAnnot.HoleLabel) + |> Doc.annot(DHAnnot.Delim); + }; + + let list_nil = mk("[]"); + let triv = mk("()"); + let wild = mk("_"); + + let open_Parenthesized = mk("("); + let close_Parenthesized = mk(")"); + + let sym_Fun = mk("fun"); + let colon_Lam = mk(":"); + let open_Lam = mk(".{"); + let close_Lam = mk("}"); + + let fix_FixF = mk("fix"); + let colon_FixF = mk(":"); + let open_FixF = mk(".{"); + let close_FixF = mk("}"); + let open_Case = mk("case"); + let close_Case = mk("end"); + + let bar_Rule = mk("|"); + let arrow_Rule = mk("=>"); + + let open_Cast = mk("<"); + let arrow_Cast = mk(Unicode.castArrowSym); + let close_Cast = mk(">"); + + let open_FailedCast = open_Cast |> Doc.annot(DHAnnot.FailedCastDelim); + let arrow_FailedCast = + mk(Unicode.castArrowSym) |> Doc.annot(DHAnnot.FailedCastDelim); + let close_FailedCast = close_Cast |> Doc.annot(DHAnnot.FailedCastDelim); +}; + +let mk_EmptyHole = (~selected=false, (u, i)) => + Delim.empty_hole((u, i)) + |> Doc.annot(DHAnnot.EmptyHole(selected, (u, i))); + +let mk_Keyword = (u, i, k) => + Doc.text(ExpandingKeyword.to_string(k)) + |> Doc.annot(DHAnnot.VarHole(ExpandingKeyword(k), (u, i))); + +let mk_IntLit = n => Doc.text(string_of_int(n)); + +let mk_FloatLit = (f: float) => + switch (f < 0., Float.is_infinite(f), Float.is_nan(f)) { + | (false, true, _) => Doc.text("Inf") + /* TODO: NegInf is temporarily introduced until unary minus is introduced to Hazel */ + | (true, true, _) => Doc.text("NegInf") + | (_, _, true) => Doc.text("NaN") + | _ => Doc.text(string_of_float(f)) + }; + +let mk_BoolLit = b => Doc.text(string_of_bool(b)); + +let mk_Cons = (hd, tl) => Doc.(hcats([hd, text("::"), tl])); + +let mk_Pair = (doc1, doc2) => Doc.(hcats([doc1, text(", "), doc2])); + +let mk_Ap = (doc1, doc2) => Doc.hseps([doc1, doc2]); diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re index 03ddd3dfe1..345eccc722 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re @@ -1,5 +1,4 @@ module Doc = Pretty.Doc; -open Util; open Haz3lcore; open DHDoc; @@ -71,10 +70,6 @@ module Delim = { let open_FixF = mk(".{"); let close_FixF = mk("}"); - let open_Inj = (inj_side: InjSide.t) => - mk(StringUtil.cat([InjSide.to_string(inj_side), "("])); - let close_Inj = mk(")"); - let projection_dot = mk("."); let open_Case = mk("case"); @@ -121,32 +116,24 @@ let mk_FloatLit = (f: float) => let mk_BoolLit = b => Doc.text(string_of_bool(b)); -let mk_TagLit = Doc.text; - -let mk_Inj = (inj_side, padded_child) => - Doc.hcats([Delim.open_Inj(inj_side), padded_child, Delim.close_Inj]); +let mk_ConstructorLit = Doc.text; let mk_Cons = (hd, tl) => Doc.(hcats([hd, text("::"), tl])); -let rec mk_comma_seq = (ld, rd, l, ol) => - switch (l) { - | [] => - if (l == ol) { - Doc.(hcats([text(ld), text(rd)])); - } else { - Doc.(hcats([text(rd)])); - } - | [hd, ...tl] => - if (l == ol) { - Doc.(hcats([text(ld), hd, mk_comma_seq(ld, rd, tl, ol)])); - } else { - Doc.(hcats([text(", "), hd, mk_comma_seq(ld, rd, tl, ol)])); - } +let mk_comma_seq = (ld, rd, l) => { + let rec mk_comma_seq_inner = l => { + switch (l) { + | [] => [] + | [hd] => [hd] + | [hd, ...tl] => Doc.([hd, text(", ")] @ mk_comma_seq_inner(tl)) + }; }; + Doc.(hcats([text(ld)] @ mk_comma_seq_inner(l) @ [text(rd)])); +}; -let mk_ListLit = l => mk_comma_seq("[", "]", l, l); +let mk_ListLit = l => mk_comma_seq("[", "]", l); -let mk_Tuple = elts => mk_comma_seq("(", ")", elts, elts); +let mk_Tuple = elts => mk_comma_seq("", "", elts); let mk_Ap = (doc1, doc2) => Doc.(hcats([doc1, text("("), doc2, text(")")])); diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei b/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei index 0faefff5d8..0763fdb608 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei @@ -48,9 +48,6 @@ module Delim: { let open_FixF: DHDoc.t; let close_FixF: DHDoc.t; - let open_Inj: InjSide.t => DHDoc.t; - let close_Inj: DHDoc.t; - let open_Case: DHDoc.t; let close_Case: DHDoc.t; @@ -84,12 +81,10 @@ let mk_FloatLit: float => Pretty.Doc.t('a); let mk_BoolLit: bool => Pretty.Doc.t('a); -let mk_TagLit: string => Pretty.Doc.t('a); +let mk_ConstructorLit: string => Pretty.Doc.t('a); let mk_StringLit: string => Pretty.Doc.t('a); -let mk_Inj: (InjSide.t, Pretty.Doc.t(DHAnnot.t)) => Pretty.Doc.t(DHAnnot.t); - let mk_Cons: (Pretty.Doc.t('a), Pretty.Doc.t('a)) => Pretty.Doc.t('a); let mk_ListLit: list(Pretty.Doc.t('a)) => Pretty.Doc.t('a); diff --git a/src/haz3lweb/view/dhcode/layout/HTypDoc.re b/src/haz3lweb/view/dhcode/layout/HTypDoc.re index d2f561afd2..b245fa0167 100644 --- a/src/haz3lweb/view/dhcode/layout/HTypDoc.re +++ b/src/haz3lweb/view/dhcode/layout/HTypDoc.re @@ -105,17 +105,37 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { ) |> hcats; (center, true); - | Sum(ty1, ty2) => - let (d1, d2) = - mk_right_associative_operands(Typ.precedence_Sum, ty1, ty2); - ( + | Rec(x, ty) => ( hcats([ - d1, - hcats([choices([linebreak(), space()]), text("| ")]), - d2, + text("Rec " ++ x ++ ".{"), + ( + (~enforce_inline) => + annot(HTypAnnot.Step(0), mk(~enforce_inline, ty)) + ) + |> pad_child(~enforce_inline), + mk_delim("}"), ]), parenthesize, - ); + ) + | Sum(sum_map) => + let center = + List.mapi( + (i, (ctr, ty)) => + switch (ty) { + | None => annot(HTypAnnot.Step(i + 1), text(ctr)) + | Some(ty) => + annot( + HTypAnnot.Step(i + 1), + hcats([text(ctr ++ "("), mk'(ty), text(")")]), + ) + }, + sum_map, + ) + |> ListUtil.join( + hcats([text(" +"), choices([linebreak(), space()])]), + ) + |> hcats; + (center, true); }; let doc = annot(HTypAnnot.Term, doc); parenthesize ? Doc.hcats([mk_delim("("), doc, mk_delim(")")]) : doc; diff --git a/src/haz3lweb/www/index.html b/src/haz3lweb/www/index.html index 831a967f44..cd9cc8aa2a 100644 --- a/src/haz3lweb/www/index.html +++ b/src/haz3lweb/www/index.html @@ -12,13 +12,13 @@ -
-
-
- - +
+
+
+ +
-

loading

+ loading
diff --git a/src/haz3lweb/www/style.css b/src/haz3lweb/www/style.css index a8396d3c60..3c126149e6 100644 --- a/src/haz3lweb/www/style.css +++ b/src/haz3lweb/www/style.css @@ -57,7 +57,6 @@ --top-bar-text: #a79f89; --test-panel-bkg: #f8ebc6; - --delim-color: #586e75; --code-emphasis: #ce9600; --err-color: red; @@ -72,9 +71,24 @@ /* SORT COLORS */ + --nul-text-color: red; + --nul-off-color: var(--nul-text-color); + --nul-delim-color: var(--nul-text-color); + --nul-shadow-color: var(--nul-text-color); + --nul-bg-color: #ffacac; + --nul-bg-off-color: var(--nul-bg-color); + + --any-text-color: var(--nul-text-color); + --any-off-color: var(--nul-off-color); + --any-delim-color: var(--nul-delim-color); + --any-shadow-color: var(--nul-shadow-color); + --any-bg-color: var(--nul-bg-color); + --any-bg-off-color: var(--nul-bg-off-color); + --exp-text-color: var(--light-text-color); - --exp-shadow-color: #c4b599; --exp-off-color: #b1a47f; + --exp-delim-color: var(--light-text-color); + --exp-shadow-color: #c4b599; --exp-bg-color: #ebdfc5; --exp-bg-off-color: #feddb3; @@ -85,28 +99,26 @@ --pat-bg-color: #b2e8ff; --pat-bg-off-color: #d7f3ff; + --tpat-text-color: #16c8dc; + --tpat-off-color: #13d2d2; + --tpat-delim-color: #a2fbf9; + --tpat-shadow-color: var(--pat-off-color); + --tpat-bg-color: #b2fbff; + --tpat-bg-off-color: #d7fff7; + --typ-text-color: #772cff; - /*#24ae62;*/ --typ-off-color: #975dff; - /*#7fc97f;*/ --typ-delim-color: #cfb5ff; - /*#aee5c6;*/ --typ-shadow-color: var(--typ-off-color); --typ-bg-color: #f2ccff; - /*#bdf5c4;*/ --typ-bg-off-color: #f9e8ff; - --rul-text-color: #a6b29a; - /*#24ae62;*/ - --rul-off-color: #bcc29b; - /*#7fc97f;*/ - --rul-bg-color: #e7ead6; - /*#bdf5c4;*/ - --rul-shadow-color: var(--rul-off-color); - --rul-delim-color: #aee5c6; - - --nul-bg-color: #ffacac; - --nul-shadow-color: #690000; + --rul-text-color: var(--exp-text-color); + --rul-off-color: var(--exp-off-color); + --rul-delim-color: #ccc2af; + --rul-shadow-color: var(--exp-shadow-color); + --rul-bg-color: var(--exp-bg-color); + --rul-bg-off-color: var(--exp-bg-off-color); /* END SORT COLORS */ @@ -138,6 +150,7 @@ --caret-position-z: 13; --current-caret-pos-z: 15; --caret-z: 14; + --docs-highlight-z:8; --type-inspector-z: 14; --top-bar-z: 15; @@ -234,18 +247,69 @@ svg { } } -/* PAGE */ +body { + /* Default UI font */ + font-family: 'Helvetica Neue'; +} -#page { +/* LOADING: This shows before the app is loaded */ + +#container { + position: fixed; + top: 0; + left: 0; height: 100vh; width: 100vw; - position: fixed; - top: 0%; - left: 0%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; background-color: var(--light-page-color); color: var(--light-text-color); + font-size: 1.75em; + font-style: italic; +} + +#container .loading { display: flex; flex-direction: column; + align-items: center; +} + +#container .loading .spinner { + display: flex; + align-items: center; + justify-content: center; +} + +#container .loading .spinner .spinner-nut { + position: fixed; + transform: scale(0.25); + filter: invert(); +} + +/* PAGE */ + +#page { + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + display: grid; + grid-template: 2.75em minmax(0, 1fr) 2em / 1fr fit-content(16em); + background-color: var(--light-page-color); + color: var(--light-text-color); +} + +#main { + grid-row: 2; + grid-column: 1 / span 1; + overflow: auto; +} + +select { + cursor: pointer; } #font-specimen { @@ -256,7 +320,6 @@ svg { #font-specimen, .code-container, .DHCode, -.cursor-inspector, .context-entry, .typ-view { line-height: var(--line-height); @@ -266,10 +329,6 @@ svg { font-size: 13pt; } -body { - font-family: 'Helvetica Neue'; -} - #editor-mode, .cell-caption, .cell-prompt, @@ -283,85 +342,76 @@ body { /* TOP BAR */ #top-bar { - box-sizing: border-box; - width: 100%; - min-width: fit-content; - padding: 0.75em; - padding-left: 3.5em; - /* to accommodate Hazel icon */ + grid-row: 1 / span 1; + grid-column: 1 / span 2; + z-index: var(--top-bar-z); display: flex; - background-color: var(--light-page-color); + align-items: center; + gap: 1em; + border-bottom: 0.6px solid #c7b480; } -#top-bar-content { - display: flex; - justify-content: space-between; - width: 100%; - max-width: 68vw; +#top-bar #title { + color: #a69460; } -#top-left-bar { +#top-bar .menu { display: flex; + transform-origin: top; + transform: scaleY(0); + transition: transform 0.07s ease; + position: fixed; + top: 2.75em; + left: 0; + width: 2.75em; + padding-top: 1em; + padding-bottom: 1em; gap: 1em; + flex-direction: column; + justify-content: center; + align-items: center; + background-color: #a69461; } -#top-right-bar { +#top-bar .menu:hover, +#top-bar .menu-icon:hover+.menu { + transform: scaleY(1); display: flex; - justify-content: right; - gap: 1em; + border-radius: 0 0 1.3em 0; } #top-bar .menu-icon { width: 2.75em; height: 2.75em; - position: fixed; - top: 0; - left: 0; display: flex; justify-content: center; align-items: center; background-color: var(--top_bar_icon_fill); cursor: pointer; + color: white; + /*border-radius: 0 0 1.1em 0;*/ + transition: all 0.1s ease-in; } -#top-bar .menu:hover, -#top-bar .menu-icon:hover+.menu { - transform: scaleY(1); - display: flex; +#top-bar .menu-icon:hover { + border-radius: 0; } -#top-bar .menu { - /*display: none;*/ - display: flex; - transform-origin: top; - transform: scaleY(0); - transition: transform 0.07s ease; - position: fixed; - top: 2.75em; - left: 0; - width: 2.75em; - padding-top: 1em; - padding-bottom: 1em; - gap: 1em; - flex-direction: column; - justify-content: center; - align-items: center; - background-color: #a69461; +#top-bar .menu-icon svg { + fill: var(--light-page-color); } -#top-bar .menu-icon:hover .menu-icon-inner { +#top-bar .menu-icon:hover svg, +#top-bar .menu-icon svg:hover { + height: 1.6em; + width: 1.6em; animation: jello 0.6s ease 0s 1 normal forwards; } -#top-bar .icon:hover svg, -.menu-icon:hover .menu-icon-inner svg { +#top-bar .icon:hover svg { transform: scale(130%); } -#top-bar .menu-icon-inner.icon svg { - fill: var(--light-page-color); -} - #top-bar .menu .icon:hover svg { animation: wobble 0.6s ease 0s 1 normal forwards; filter: brightness(1.2); @@ -391,7 +441,6 @@ body { } #top-bar #editor-mode { - font-size: 0.7em; color: #fdf6e3; display: flex; align-items: center; @@ -399,9 +448,9 @@ body { cursor: pointer; user-select: none; background-color: #c7b480; - border-radius: 1em; - padding: 0.2em 0.5em 0.2em 0.5em; + border-radius: 0.4em 1em 1em 0.4em; transition: width 0.1s ease-in; + font-size: 0.7em; } #top-bar #editor-mode .icon { @@ -411,6 +460,10 @@ body { align-items: center; } +#top-bar #editor-mode .icon:hover { + filter: brightness(0.45) sepia(1) hue-rotate(15deg) saturate(50); +} + #top-bar #editor-mode .icon svg { fill: var(--light-page-color); } @@ -419,24 +472,45 @@ body { background-color: #99854a; } +#top-bar #editor-mode .mode-name{ + border-radius: 0.4em 1em 1em 0.4em; + padding: 0 0.5em 0 0.5em; + background-color: #a69460; + border-bottom: 0.7px solid #ebe0c2; + color: #fdf6e3; +} + +#top-bar #editor-mode .mode-name select:hover, +#top-bar #editor-mode select:hover { + color: #fad56f; +} #top-bar #editor-mode .icon svg { - width: 15px; height: 15px; } -#top-bar #editor-mode:hover { - transform: scale(110%); -} - -#editor-mode .toggle-switch.active .toggle-knob { +#top-bar #editor-mode .toggle-switch.active .toggle-knob { filter: grayscale(1) sepia(1); } -#editor-mode .toggle-switch .toggle-knob { +#top-bar #editor-mode .toggle-switch .toggle-knob { filter: grayscale(1) sepia(1) opacity(0.3); } +#top-bar #editor-mode select { + background-color: #0000; + border: none; + color: white; + font-size: 1em; + height: 1.7em; +} + +#top-bar #editor-mode select:focus-visible { + background-color: #0000 !important; + color: #fad56f !important; + outline: none; +} + /* END TOP BAR */ .editor { @@ -456,8 +530,7 @@ body { } .editor.single { - padding-top: 2em; - padding-left: 2em; + padding: 2em 2em 4em 2em; } #mousedown-overlay { @@ -474,14 +547,17 @@ body { position: relative; } +.editor .code-container { + cursor: text; +} + .code { /*white-space: nowrap;*/ } .cell-container { width: fit-content; - min-width: 70vw; - max-width: 70vw; + /*min-width: 24em;*/ } .cell-container .cell-item:first-child { @@ -501,7 +577,6 @@ body { .title-cell .title-text { font-size: 1.5rem; - font-family: "Helvetica Neue", sans-serif; font-weight: bold; color: var(--light-text-color); } @@ -523,8 +598,6 @@ body { border-left: 1px solid var(--top_bar_icon_fill); } -.cell.school {} - .cell.selected { border-left: 1px solid var(--cell-selected-accent); background-color: #fffcf3; @@ -642,58 +715,10 @@ body { vector-effect: non-scaling-stroke; } -.child-line.Exp { - stroke: var(--exp-shadow-color); -} - -.child-line.Pat { - stroke: var(--pat-shadow-color); -} - -.child-line.Typ { - stroke: var(--typ-shadow-color); -} - -.child-line.Rul { - stroke: var(--rul-shadow-color); -} - -/*TODO(andrew): clean up text classes*/ -.code .text-Pat { - color: var(--pat-text-color); -} - -.code .delim.text-Pat { - color: var(--pat-delim-color); - font-weight: bold; -} - -.code .text-Exp { - color: var(--exp-text-color); -} - -.code .text-Typ { - color: var(--typ-text-color); -} - -.code .delim.text-Typ { - color: var(--typ-delim-color); +.code .delim { font-weight: bold; } -.code .text-Rul { - color: var(--rul-text-color); -} - -.code .delim.text-Rul { - color: var(--rul-delim-color); - font-weight: bold; -} - -/* TOKEN COLORS */ - -.code .token.mono {} - .code .token.mono-string-lit { color: var(--string-lit-color); } @@ -703,7 +728,7 @@ body { } .code .token.delim { - color: var(--delim-color); + color: var(--exp-delim-color); font-weight: bold; } @@ -734,205 +759,174 @@ svg.tile-selected { filter: url(#raised-drop-shadow-Nul) !important; } - -.tile-path.Exp { - filter: url(#drop-shadow-Exp); -} - -.tile-path.Exp.indicated { - fill: var(--exp-bg-color); -} - -.tile-path.Exp.indicated-caret { - fill: var(--exp-bg-off-color); -} - -#drop-shadow-Exp .tile-drop-shadow, -#raised-drop-shadow-Exp .tile-drop-shadow { - flood-color: var(--exp-shadow-color); -} - -.tile-path.Pat { - /*stroke: var(--pat-text-color);*/ - filter: url(#drop-shadow-Pat); -} - -.tile-path.Pat.indicated { - fill: var(--pat-bg-off-color); -} - -.tile-path.Pat.indicated-caret { - fill: var(--pat-bg-color); -} - -.tile-path.Pat.raised { - filter: url(#raised-drop-shadow-Pat); -} - -#drop-shadow-Pat .tile-drop-shadow, -#raised-drop-shadow-Pat .tile-drop-shadow { - flood-color: var(--pat-shadow-color); -} - -.tile-path.Typ { - filter: url(#drop-shadow-Typ); -} - -.tile-path.Typ.indicated { - fill: var(--typ-bg-off-color); -} - -.tile-path.Typ.indicated-caret { - fill: var(--typ-bg-color); - /* TODO(andrew) */ -} - -.tile-path.Typ.raised { - filter: url(#raised-drop-shadow-Typ); -} - -#drop-shadow-Typ .tile-drop-shadow, -#raised-drop-shadow-Typ .tile-drop-shadow { - flood-color: var(--typ-shadow-color); -} - -.tile-path.Rul { - filter: url(#drop-shadow-Rul); -} - -.tile-path.Rul.indicated { - fill: var(--rul-bg-color); -} - -.tile-path.Rul.indicated-caret { - fill: var(--rul-bg-color); -} - -.tile-path.Rul.raised { - filter: url(#raised-drop-shadow-Rul); +.caret-position-path { + vector-effect: non-scaling-stroke; + stroke-width: 0.1px; } -#drop-shadow-Rul .tile-drop-shadow, -#raised-drop-shadow-Rul .tile-drop-shadow { - flood-color: var(--rul-shadow-color); +.caret-position-path.outer-cousin { + stroke: var(--bar-color); + fill: var(--bar-color); } -.tile-path.Nul { - filter: url(#drop-shadow-Nul); +@property --color { + syntax: ''; + /* <- defined as type number for the transition to work */ + initial-value: #000000; + inherits: false; } -.tile-path.Nul.indicated { - fill: var(--nul-bg-color); +#caret-bar { + position: absolute; + height: 100%; + top: 0; + left: 0; + width: 2px; + transform: translate(-50%, 0%); + z-index: var(--caret-bar-z); } -.tile-path.Nul.indicated-caret { - fill: var(--nul-bg-color); -} +/* TOKEN COLORS */ -.tile-path.Nul.raised { - filter: url(#raised-drop-shadow-Nul); +.code .text-Nul { color: var(--nul-text-color); } +.code .text-Any { color: var(--any-text-color); } +.code .text-Exp { color: var(--exp-text-color); } +.code .text-Pat { color: var(--pat-text-color); } +.code .text-Typ { color: var(--typ-text-color); } +.code .text-Rul { color: var(--rul-text-color); } +.code .text-TPat { color: var(--tpat-text-color); } + +.code .delim.text-Nul { color: var(--nul-delim-color); } +.code .delim.text-Any { color: var(--any-delim-color); } +.code .delim.text-Exp { color: var(--exp-delim-color); } +.code .delim.text-Pat { color: var(--pat-delim-color); } +.code .delim.text-Typ { color: var(--typ-delim-color); } +.code .delim.text-Rul { color: var(--rul-delim-color); } +.code .delim.text-TPat { color: var(--tpat-delim-color); } + +.tile-path.Nul { filter: url(#drop-shadow-Nul); } +.tile-path.Any { filter: url(#drop-shadow-Any); } +.tile-path.Exp { filter: url(#drop-shadow-Exp); } +.tile-path.Pat { filter: url(#drop-shadow-Pat); } +.tile-path.Typ { filter: url(#drop-shadow-Typ); } +.tile-path.Rul { filter: url(#drop-shadow-Rul); } +.tile-path.TPat { filter: url(#drop-shadow-TPat); } + +.tile-path.Nul.indicated { fill: var(--nul-bg-color); } +.tile-path.Any.indicated { fill: var(--any-bg-color); } +.tile-path.Exp.indicated { fill: var(--exp-bg-color); } +.tile-path.Pat.indicated { fill: var(--pat-bg-off-color); } +.tile-path.Typ.indicated { fill: var(--typ-bg-off-color); } +.tile-path.Rul.indicated { fill: var(--rul-bg-color); } +.tile-path.TPat.indicated { fill: var(--tpat-bg-off-color); } + +.tile-path.Nul.indicated-caret { fill: var(--nul-bg-color); } +.tile-path.Any.indicated-caret { fill: var(--any-bg-color); } +.tile-path.Exp.indicated-caret { fill: var(--exp-bg-off-color); } +.tile-path.Pat.indicated-caret { fill: var(--pat-bg-color); } +.tile-path.Typ.indicated-caret { fill: var(--typ-bg-color); } +.tile-path.Rul.indicated-caret { fill: var(--rul-bg-color); } +.tile-path.TPat.indicated-caret { fill: var(--tpat-bg-color); } + +.tile-path.Nul.raised { filter: url(#raised-drop-shadow-Nul); } +.tile-path.Any.raised { filter: url(#raised-drop-shadow-Any); } +.tile-path.Exp.raised { filter: url(#raised-drop-shadow-Exp); } +.tile-path.Pat.raised { filter: url(#raised-drop-shadow-Pat); } +.tile-path.Typ.raised { filter: url(#raised-drop-shadow-Typ); } +.tile-path.Rul.raised { filter: url(#raised-drop-shadow-Rul); } +.tile-path.TPat.raised { filter: url(#raised-drop-shadow-TPat); } + +.child-line.Nul { stroke: var(--nul-shadow-color); } +.child-line.Any { stroke: var(--any-shadow-color); } +.child-line.Exp { stroke: var(--exp-shadow-color); } +.child-line.Pat { stroke: var(--pat-shadow-color); } +.child-line.Typ { stroke: var(--typ-shadow-color); } +.child-line.Rul { stroke: var(--rul-shadow-color); } +.child-line.TPat { stroke: var(--tpat-shadow-color); } + +#drop-shadow-Nul .tile-drop-shadow { flood-color: var(--nul-shadow-color); } +#drop-shadow-Any .tile-drop-shadow { flood-color: var(--any-shadow-color); } +#drop-shadow-Exp .tile-drop-shadow { flood-color: var(--exp-shadow-color); } +#drop-shadow-Pat .tile-drop-shadow { flood-color: var(--pat-shadow-color); } +#drop-shadow-Typ .tile-drop-shadow { flood-color: var(--typ-shadow-color); } +#drop-shadow-Rul .tile-drop-shadow { flood-color: var(--rul-shadow-color); } +#drop-shadow-TPat .tile-drop-shadow { flood-color: var(--tpat-shadow-color); } + +#raised-drop-shadow-Nul .tile-drop-shadow { flood-color: var(--nul-shadow-color); } +#raised-drop-shadow-Any .tile-drop-shadow { flood-color: var(--any-shadow-color); } +#raised-drop-shadow-Exp .tile-drop-shadow { flood-color: var(--exp-shadow-color); } +#raised-drop-shadow-Pat .tile-drop-shadow { flood-color: var(--pat-shadow-color); } +#raised-drop-shadow-Typ .tile-drop-shadow { flood-color: var(--typ-shadow-color); } +#raised-drop-shadow-Rul .tile-drop-shadow { flood-color: var(--rul-shadow-color); } +#raised-drop-shadow-TPat .tile-drop-shadow { flood-color: var(--tpat-shadow-color); } + +/* OTHER SORT COLORS */ + +.ci-header-Nul { + background-color: var(--nul-bg-color); + color: var(--nul-off-color); +} +.ci-header-Any { + background-color: var(--any-bg-color); + color: var(--any-off-color); +} +.ci-header-Exp { + background-color: var(--exp-bg-color); + color: var(--exp-off-color); } - -#drop-shadow-Nul .tile-drop-shadow, -#raised-drop-shadow-Nul .tile-drop-shadow { - flood-color: var(--nul-shadow-color); +.ci-header-Pat { + background-color: var(--pat-bg-color); + color: var(--pat-off-color); } - -.caret-position-path { - vector-effect: non-scaling-stroke; - stroke-width: 0.1px; +.ci-header-Typ { + background-color: var(--typ-bg-color); + color: var(--typ-off-color); } - -.caret-position-path.outer-cousin { - stroke: var(--bar-color); - fill: var(--bar-color); +.ci-header-Rul { + background-color: var(--rul-bg-color); + color: var(--rul-off-color); } - -.caret-position-path.Exp.sibling { - stroke: var(--exp-text-color); - fill: var(--exp-text-color); +.ci-header-TPat { + background-color: var(--tpat-bg-color); + color: var(--tpat-off-color); } +/* is this used? */ +.caret-position-path.Exp.sibling, .caret-position-path.Exp.inner-cousin { stroke: var(--exp-text-color); fill: var(--exp-text-color); } - .caret-position-path.Pat.sibling, .caret-position-path.Pat.inner-cousin { stroke: var(--pat-text-color); fill: var(--pat-text-color); } +.caret-position-path.Typ.sibling, +.caret-position-path.Typ.inner-cousin { + stroke: var(--typ-text-color); + fill: var(--typ-text-color); +} +/* is this used? */ .caret-position-path.Exp.anchor, .caret-position-path.Exp.current-caret-pos { stroke: var(--exp-shadow-color); fill: var(--exp-shadow-color); } - .caret-position-path.Pat.anchor, .caret-position-path.Pat.current-caret-pos { stroke: var(--pat-text-color); fill: var(--pat-text-color); } - .caret-position-path.Typ.anchor, .caret-position-path.Typ.current-caret-pos { stroke: var(--typ-text-color); fill: var(--typ-text-color); } -@property --color { - syntax: ''; - /* <- defined as type number for the transition to work */ - initial-value: #000000; - inherits: false; -} - -#caret-bar { - position: absolute; - height: 100%; - top: 0; - left: 0; - width: 2px; - transform: translate(-50%, 0%); - z-index: var(--caret-bar-z); -} - -#caret-bar.Exp { - background-color: var(--exp-shadow-color); -} +/* END SORT COLORS */ -#caret-bar.Pat { - background-color: var(--pat-text-color); -} - -.sort-label { - border-radius: 2px; - font-weight: 600; -} - -.sort-label.typ { - background-color: var(--typ-bg-color); -} - -.sort-label.pat { - background-color: var(--pat-bg-color); -} - -.sort-label.exp { - background-color: var(--exp-bg-color); -} - -.sort-label.Exp { - /*color: var(--light-page-color);*/ - color: var(--exp-shadow-color); -} - -.sort-label.Pat { - /*color: var(--light-page-color);*/ - color: var(--pat-text-color); -} .keyboard-arrow { position: relative; @@ -1048,6 +1042,10 @@ svg.tile-selected { .typ-view { color: var(--typ-text-color); display: flex; +} + +.kind-view { + display: flex; gap: 0.5em; } @@ -1057,62 +1055,48 @@ svg.tile-selected { gap: 0em; } +.typ-alias-view { + color: var(--tpat-text-color); + display: flex; +} + .typ-mod { vertical-align: super; font-size: 0.7em; } -.term-tag { +.ci-header { padding: 0em 0.6em 0em 0em; - /*border-radius: 0 0.4em 0.4em 0;*/ border-radius: 0 1.1em 0 0; display: flex; gap: 0.5em; - color: #0006; - font-weight: bolder; - text-transform: uppercase; align-items: center; } -.term-tag.error { +.ci-header.error { background-color: var(--err-color); color: #830000 !important; /* HACK(andrew) */ } -.term-tag-typ { - background-color: var(--typ-bg-color); - color: var(--typ-off-color); -} - -.term-tag-pat { - background-color: var(--pat-bg-color); - color: var(--pat-off-color); -} - -.term-tag-exp { - background-color: var(--exp-bg-color); - color: var(--exp-off-color); -} - -.term-tag-rul { - background-color: var(--rul-bg-color); - color: var(--rul-off-color); +.term-tag { + font-weight: bolder; + text-transform: uppercase; } /* CURSOR INSPECTOR */ .cursor-inspector { - z-index: var(--type-inspector-z); display: flex; + /*z-index: var(--type-inspector-z); gap: 0.5em; color: #8c795b; - /*border-radius: 0.3em;*/ border-radius: 0 1.1em 0 0; padding-right: 0.6em; - /* border-right: 1px solid #daca9f; */ - background-color: #fbecaa; - /*#fefcf3;*/ + align-items: stretch;*/ +} + +.cursor-inspector.no-info { align-items: center; } @@ -1120,131 +1104,180 @@ svg.tile-selected { border-color: var(--err-color); } -.cursor-inspector .extra { - z-index: 30; - position: fixed; - width: max-content; - /* top: 3.5em; */ - left: 1.2em; - bottom: 4.5em; - display: none; - gap: 0.5em; - font-size: 0.5em; -} - -.cursor-inspector:hover .extra, -.cursor-inspector .extra.visible, -.cursor-inspector:hover .context-inspector, +.cursor-inspector .gamma:hover + .context-inspector, .context-inspector.visible { display: flex; } -.cursor-inspector .extra .syntax-class { - color: var(--top_bar_icon_fill); -} - -.cursor-inspector .extra .id { - color: #8f8054; -} - .cursor-inspector .info { display: flex; - align-items: center; + align-items: stretch; gap: 0.5em; color: #8c795b; } -.cursor-inspector .info .happy, +.cursor-inspector .info .ok, .cursor-inspector .info .error { display: flex; + align-items: center; gap: 0.5em; + white-space: nowrap; } -.cursor-inspector .info .error, -.cursor-inspector .info .error .typ-view { +.cursor-inspector .info .error { color: var(--err-color); } /* CONTEXT INSPECTOR */ .context-inspector { - display: none; + /* below triggers chrome jank bug */ + /*scroll-snap-type: y mandatory;*/ + direction: rtl; + position: absolute; z-index: 20; - position: fixed; - left: 0.2em; - bottom: 2.1em; + bottom: 1.9em; min-width: 10em; - max-width: 14em; - max-height: 12em; + max-height: 11.26em; overflow: auto; - padding: 0.2em; - padding-bottom: 1.5em; + display: none; + flex-direction: column; + align-items: flex-end; + padding-left: 0.1em; + padding-right: 0.5em; white-space: nowrap; - border-radius: 0.2em; + border-radius: 0 0.2em 0em 0; color: #586e75; - border-left: 1px solid #daca9f; - border-right: 1px solid #daca9f; + border-top: 1px solid #e6ce8f; + border-right: 1px solid #c7b480; + border-bottom: 1px solid #c7b480; background-color: #f7ebc5; - box-shadow: 0px 3px 0px #77580255; + box-shadow: 0px 20px 20px #77580255; + scrollbar-color: #c7b480 #e4d6a6; + scrollbar-width: thin; +} +@supports (-moz-appearance:none) { + .context-inspector { scroll-snap-type: y mandatory; } +} + +.context-inspector::-webkit-scrollbar { + background-color: #e4d6a6; +} + +::-webkit-scrollbar-thumb { + background-color: #c7b480; + border-radius: 0 0.5em 0.5em 0em; } .context-entry { - cursor: pointer; + box-sizing: border-box; + scroll-snap-align: end; + direction: ltr; display: flex; gap: 0.5em; + max-width: 17em; + -webkit-mask-image: linear-gradient(to right, black 13em, transparent); + border-top: 0.5px solid #0000; + border-bottom: 0.5px solid #e2d4a9; + padding-left: 0.3em; + padding-right: 0.3em; +} + +.context-entry:hover { + max-width: 400em; + -webkit-mask-image: none; + background-image: linear-gradient(0deg, rgb(138 99 32), 1%, #f0e1b2, 10%, #f3e6be); + border-radius: 0.1em 0.6em 0.1em 0.6em; + border-top: 0.5px solid #ffffff; + border-bottom: 0.5px solid rgb(51 36 11); +} + +.context-entry .name{ + cursor: pointer; +} + +.context-entry .name:hover { + filter: brightness(0); +} + +.context-entry .typ-view:hover { + /*filter: brightness(1.25) hue-rotate(10deg);*/ +} + +.context-entry .seperator { + color: #c7b480; } /* END STATICS*/ -.bottom-bar { - z-index: var(--result-z); - /*max-height: 3.2em; - overflow-y: auto;*/ - left: 0; - width: 100%; +#bottom-bar { + grid-row: 3 / span 1; + grid-column: 1 / span 2; display: flex; align-items: center; gap: 1em; - background-color: var(--top_bar_icon_fill); - color: #fdf6e3; justify-content: space-between; + align-items: stretch; + background-color: #fbecaa; + border-top: 0.6px solid #c7b480; } -.bottom-bar .cursor-inspector .gamma { - background-color: #b69f79; - padding: 0.16em; +#bottom-bar .icon { + display: flex; + padding: 0.2em; +} + +#bottom-bar .id { + display: flex; + gap: 1em; + font-size: 0.6em; + align-items: center; + padding-left: 1em; + padding-right: 1em; + white-space: nowrap; + color: #a69461; +} + +#bottom-bar .syntax-class { display: flex; + align-items: center; +} + +#bottom-bar .cursor-inspector .gamma { + cursor: pointer; + display: flex; + align-items: center; + font-family: math; + font-weight: normal; + background-color: #b69f79; border-radius: 0 1.1em 0 0; padding-left: 0.5em; - padding-right: 0.5em; + padding-right: 0.7em; color: var(--light-page-color); + height: 100%; +} + +#bottom-bar .cursor-inspector .gamma:hover, +#bottom-bar .cursor-inspector .gamma.visible { + color: gold; + background-color: #907b5a; + border-radius: 0; +} + +#side-bar { + grid-row: 2 / span 1; + grid-column: 2 / span 1; + border-left: 0.6px solid #c7b480; } .lang-doc { - z-index: 20; - position: fixed; - right: 1em; - /* top: 3.8em; */ - /* bottom: 1.8em; */ - width: 25vw; - height: 100vh; - overflow: auto; padding: 0.2em; - padding-bottom: 1.5em; white-space: nowrap; - color: var(--light-text-color); - background-color: #f7ebc5; - /*#fbebaa;*/ } .comment { color: #a0c1aa; } -/* TODO slightly hacky way to be able to scroll to all content vertically - can't see scrollbars on the bottom even when there though...*/ -.lang-doc .content { - padding-bottom: 8em; -} - /* TODO seems like should be better way to ignore inconsistentcy colorings...*/ .lang-doc .code .text-Pat.mono-inconsistent { color: var(--pat-text-color); @@ -1263,12 +1296,24 @@ svg.tile-selected { } .lang-doc .code .token.delim-inconsistent { - color: var(--delim-color); + color: var(--exp-delim-color); font-weight: bold; } +.lang-doc #examples { + display: flex; + flex-direction: column; + gap: 0.6em; +} + .lang-doc .example { - border-bottom: 1px dotted #a69461; + display: flex; + flex-direction: column; +} + +.lang-doc .example + .example { + border-top: 1px dotted #c7b480; + padding-top: 0.6em; } .lang-doc .example .code-text { @@ -1278,6 +1323,7 @@ svg.tile-selected { .lang-doc .example .ex-result { display: flex; align-items: center; + gap: 0.5em; padding-top: 5px; } @@ -1297,7 +1343,9 @@ svg.tile-selected { transform-origin: top; transform: scaleY(0); transition: transform 0.07s ease; - background-color: var(--top_bar_icon_fill); + background-color: #f1e5bf; + border: 0.7px solid #e1c475; + border-top: none; } .specificity-options-menu .selected { @@ -1316,6 +1364,20 @@ svg.tile-selected { .lang-doc .top-bar .close { cursor: pointer; + font-family: 'Source Code Pro'; + color: var(--top_bar_icon_fill); + width: 1.2em; + height: 1.2em; + border-radius: 2em; + display: flex; + align-items: end; + justify-content: center; +} + +.lang-doc .top-bar .close:hover { + animation: wobble 0.4s ease 0s 1 normal none; + color: var(--light-page-color); + background-color: #c7b480; } .lang-doc .section { @@ -1331,6 +1393,9 @@ svg.tile-selected { .lang-doc .section .section-title { text-transform: uppercase; font-weight: bold; + color: #a69460; + font-size: 0.8em; + padding: 0 0 0.5em 0; } .lang-doc .section .explanation-contents { @@ -1338,27 +1403,27 @@ svg.tile-selected { } .highlight-blue { - background-color: rgb(180, 203, 240); + background-color: rgb(255 0 255 / 20%); } .highlight-code-blue { - fill: rgb(180, 203, 240); + fill: rgb(255 0 255 / 20%); } .highlight-pink { - background-color: rgb(242, 177, 182); + background-color: rgb(0 255 255 / 40%); } .highlight-code-pink { - fill: rgb(242, 177, 182); + fill: rgb(0 255 255 / 40%); } .highlight-teal { - background-color: rgb(127, 243, 245); + background-color: rgb(0 255 0 / 20%); } .highlight-code-teal { - fill: rgb(127, 243, 245); + fill: rgb(0 255 0 / 20%); } .highlight-orange { @@ -1405,10 +1470,9 @@ div.expandable-target { svg.expandable { - fill: rgba(19, 17, 17, 0.067); - stroke-dasharray: 4, 4; - stroke: var(--light-text-color); - stroke-width: 2px; + fill: rgb(199 180 128 / 0%); + stroke-dasharray: 3, 3; + stroke: #a69460; /* mix-blend-mode: color; */ z-index: var(--err-hole-z); } @@ -1474,7 +1538,8 @@ svg.expandable path { .result { min-height: 1.6em; - overflow: hidden; + overflow-y: hidden; + overflow-x: auto; } /* DYNAMICS - DHEXP */ @@ -1524,16 +1589,9 @@ svg.expandable path { display: inline-block; } +.DHCode .OperationError, .DHCode .CastDecoration, -.DHCode .FailedCastDecoration, -.DHCode .DivideByZero { - display: inline-block; - position: relative; - font-size: 75%; - top: -10px; -} - -.DHCode .NegativeExponent { +.DHCode .FailedCastDecoration { display: inline-block; position: relative; font-size: 75%; @@ -1554,23 +1612,6 @@ svg.expandable path { /* DYNAMICS - test panel */ -.school-panel { - color: var(--light-text-color); - min-width: 50vw; - max-width: 70vw; - /*min-width: 15em; - max-height: 100%; - overflow-y: auto; - z-index: var(--test-panel-z); - position: fixed; - right: 0; - top: 0em; - max-width: 21em;*/ - display: flex; - flex-direction: column; - gap: 0.5em; -} - .test-panel { z-index: var(--test-panel-z); display: flex; @@ -1736,16 +1777,25 @@ svg.expandable path { } .test-percent { - font-weight: bold; - font-family: 'Helvetica Neue' + height: 1.7em; + display: flex; + padding: 0 1em 0 1em; + font-size: 0.7em; + border-radius: 1em; + background-color: #c7b480; + align-items: center; + margin-left: auto; + margin-right: 1em; } .test-percent.all-pass { - color: #7cb; + background-color: #66ffcb; + color: #289f87; + animation: jello 1s ease 0s 1 normal none; } .test-percent.some-fail { - color: tan; + color: var(--light-page-color); } .test-bar .segment:first-child { @@ -1854,7 +1904,7 @@ svg.expandable path { /* END TOGGLE */ -/* Exercises */ +/* Exercise */ .exercise-code { white-space: nowrap; font-family: "Source Code Pro", monospace; @@ -1881,7 +1931,3 @@ svg.expandable path { left: -1em; } -#main { - overflow: auto; - flex: 1; -} \ No newline at end of file diff --git a/src/util/ListUtil.re b/src/util/ListUtil.re index 0ef44f38f9..7d15427aa9 100644 --- a/src/util/ListUtil.re +++ b/src/util/ListUtil.re @@ -430,3 +430,9 @@ let init_fold: (int, 'b, (int, 'b) => ('b, 'a)) => ('b, list('a)) = ); (acc, List.rev(rev_xs)); }; + +let assoc_err = (x, xs, err: string) => + switch (List.assoc_opt(x, xs)) { + | None => failwith(err) + | Some(y) => y + }; From 84602b2f085595272706c684e2ed952eabca9ef5 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 1 Aug 2023 15:50:07 -0400 Subject: [PATCH 012/229] Made tuples of functions always recursive --- src/haz3lcore/statics/Statics.re | 6 +- src/haz3lcore/statics/Term.re | 136 ++++--------------------------- 2 files changed, 18 insertions(+), 124 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index e5f7833663..76ff4e5207 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -246,8 +246,10 @@ and uexp_to_info_map = ); | Let(p, def, body) => let (p_syn, _) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); + let is_tuple_of_functions = + UPat.is_tuple_of_arrows(p) && UExp.is_tuple_of_functions(def); let (def, p_ana, m) = - if (Option.is_none(UExp.get_recursive_bindings(p, def))) { + if (!is_tuple_of_functions) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); @@ -256,7 +258,7 @@ and uexp_to_info_map = let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); - let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_ana.ty), def, m); + let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); (def, p_ana, m); }; // let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index dba1de1a13..98f18d9d57 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -90,9 +90,9 @@ module UTyp = { let rec is_arrow = (typ: t) => { switch (typ.term) { | Parens(typ) => is_arrow(typ) - | Arrow(_) => true + | Arrow(_) + | EmptyHole => true | Invalid(_) - | EmptyHole | MultiHole(_) | Int | Float @@ -304,11 +304,13 @@ module UPat = { }; let rec is_tuple_of_arrows = (pat: t) => - is_fun_var(pat) + is_var(pat) + || is_fun_var(pat) || ( switch (pat.term) { | Parens(pat) => is_tuple_of_arrows(pat) - | Tuple(pats) => pats |> List.for_all(is_fun_var) + | Tuple(pats) => + pats |> List.for_all(pat => is_var(pat) || is_fun_var(pat)) | Invalid(_) | EmptyHole | MultiHole(_) @@ -327,28 +329,6 @@ module UPat = { } ); - let rec has_var_def = (pat: t, var: Var.t) => { - switch (pat.term) { - | Var(var') => var == var' - | Parens(pat) - | TypeAnn(pat, _) - | Ap(_, pat) => has_var_def(pat, var) - | ListLit(pats) - | Tuple(pats) => List.exists(pat => has_var_def(pat, var), pats) - | Cons(pat1, pat2) => has_var_def(pat1, var) || has_var_def(pat2, var) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Wild - | Int(_) - | Float(_) - | Bool(_) - | String(_) - | Triv - | Constructor(_) => false - }; - }; - let rec get_var = (pat: t) => { switch (pat.term) { | Parens(pat) @@ -687,94 +667,12 @@ module UExp = { }; }; - let rec get_fun_var = (pat: UPat.t, e: t) => { - switch (e.term) { - | Parens(e) => get_fun_var(pat, e) - | Fun(_, e) => - switch (UPat.get_var(pat)) { - | Some(x) when has_fun_var(e, x) => Some(x) - | _ => None - } - | _ => None - }; - } - and has_fun_var = (e: t, var: Var.t) => - switch (e.term) { - | Var(var') => var == var' - | Parens(e) - | TyAlias(_, _, e) - | Test(e) - | UnOp(_, e) => has_fun_var(e, var) - | Cons(e1, e2) - | Seq(e1, e2) - | BinOp(_, e1, e2) => has_fun_var(e1, var) || has_fun_var(e2, var) - | If(e1, e2, e3) => - has_fun_var(e1, var) || has_fun_var(e2, var) || has_fun_var(e3, var) - | ListLit(es) - | Tuple(es) => List.exists(has_fun_var(_, var), es) - | Fun(pat, e) - | Let(pat, _, e) => !UPat.has_var_def(pat, var) && has_fun_var(e, var) - | Match(e, ruls) => - has_fun_var(e, var) - || List.exists( - ((pat, e)) => - !UPat.has_var_def(pat, var) && has_fun_var(e, var), - ruls, - ) - | Ap(fn, arg) => - //has_branch_var(fn, var) || - has_fun_var(fn, var) || has_fun_var(arg, var) - | DeferredAp(fn, args) => - //has_branch_var(fn, var) || - has_fun_var(fn, var) || List.exists(has_fun_var(_, var), args) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Triv - | Deferral(_) - | Bool(_) - | Int(_) - | Float(_) - | String(_) - // | Var(_) - | Constructor(_) => false + let get_fun_var = (pat: UPat.t, e: t) => + if (UPat.is_fun_var(pat) || UPat.is_var(pat) && is_fun(e)) { + UPat.get_var(pat); + } else { + None; }; - // and has_branch_var = (e: t, var: Var.t) => { - // switch (e.term) { - // | Var(var') => var == var' - // | Parens(e) - // | TyAlias(_, _, e) - // | Seq(_, e) => has_branch_var(e, var) - // | Let(pat, _, e) => - // !UPat.has_var_def(pat, var) && has_branch_var(e, var) - // | If(_, e1, e2) => has_branch_var(e1, var) || has_branch_var(e2, var) - // | Match(_, ruls) => - // List.exists( - // ((pat, e)) => - // !UPat.has_var_def(pat, var) && has_branch_var(e, var), - // ruls, - // ) - // | Ap(_) - // | DeferredAp(_) - // | Fun(_) - // | Invalid(_) - // | EmptyHole - // | MultiHole(_) - // | Triv - // | Deferral(_) - // | Bool(_) - // | Int(_) - // | Float(_) - // | String(_) - // | ListLit(_) - // | Tuple(_) - // | Test(_) - // | Cons(_) - // | UnOp(_) - // | BinOp(_) - // | Constructor(_) => false - // }; - // }; let rec get_recursive_bindings = (pat: UPat.t, e: t) => { switch (get_fun_var(pat, e)) { @@ -784,20 +682,14 @@ module UExp = { | Parens(e) => get_recursive_bindings(pat, e) | Tuple(es) => switch (UPat.get_pats(pat)) { - | Some(pats) => - let get_fun_var = pat => - List.fold_left( - (acc, e) => Option.is_none(acc) ? get_fun_var(pat, e) : acc, - None, - es, - ); - let fun_vars = pats |> List.map(get_fun_var); + | Some(pats) when List.length(pats) == List.length(es) => + let fun_vars = List.map2(get_fun_var, pats, es); if (List.exists(Option.is_none, fun_vars)) { None; } else { Some(List.map(Option.get, fun_vars)); }; - | None => None + | _ => None } | Invalid(_) | EmptyHole From 194059d0937b890d6d1dc0475ccc1cf36f9ec49d Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 1 Aug 2023 16:51:51 -0400 Subject: [PATCH 013/229] Update Statics.re --- src/haz3lcore/statics/Statics.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 76ff4e5207..91196f3f3a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -258,7 +258,7 @@ and uexp_to_info_map = let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); - let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); + let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_ana.ty), def, m); (def, p_ana, m); }; // let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); From 6cb7ca9e2bf962794943010b8600eea49f54c98d Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Mon, 7 Aug 2023 22:23:42 +0800 Subject: [PATCH 014/229] Finished porting `Constraint.re`. --- .github/workflows/deploy_branches.yml | 1 + INSTALL.md | 4 +- INSTRUCTORS.md | 2 +- Makefile | 4 +- README.md | 44 +++++----- src/haz3lcore/dynamics/Constraint.re | 112 ++++++++++++++++++++++++-- 6 files changed, 134 insertions(+), 33 deletions(-) diff --git a/.github/workflows/deploy_branches.yml b/.github/workflows/deploy_branches.yml index 928502a69e..a0046e4761 100644 --- a/.github/workflows/deploy_branches.yml +++ b/.github/workflows/deploy_branches.yml @@ -47,6 +47,7 @@ jobs: git config user.name github-deploy-action git config user.email hazel-deploy@hazel.org git add -A + git pull --no-edit git status git diff-index --quiet HEAD || (git commit -m "github-deploy-action-${BRANCH_NAME}"; git push) working-directory: ./server \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md index e3a601702c..434ece43e7 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -231,12 +231,12 @@ If the build fails, it sometimes helps to do a `make clean`. - `make win-chrome` You can also launch Hazel directly by opening -`_build/default/src/hazelweb/www/index.html` in your browser. The command `make +`_build/default/src/haz3lweb/www/index.html` in your browser. The command `make echo-html` echos that path to the terminal, so that you don't have to remember it. You can also run `make repl` to get a REPL in which you can play with the definitions -in `hazelcore`. The definitions in `hazelweb` cannot be used in the REPL because that +in `haz3lcore`. The definitions in `haz3lweb` cannot be used in the REPL because that package needs a browser environment to run. diff --git a/INSTRUCTORS.md b/INSTRUCTORS.md index 4fbeb16b37..a1ded61b5a 100644 --- a/INSTRUCTORS.md +++ b/INSTRUCTORS.md @@ -2,7 +2,7 @@ 1. Make a copy of src/haz3lweb/exercises/BlankTemplate.ml, filling in the arguments for your exercise. Make sure the module_name argument matches your module name. Use the .ml extension (for technical reasons). -2. Add your exercise to the exercise list in SchoolSettings_base.re. +2. Add your exercise to the exercise list in ExerciseSettings_base.re. 3. Compile and load Hazel, select your exercise, make sure Instructor Mode is on. diff --git a/Makefile b/Makefile index 86394c603e..cc409caf68 100644 --- a/Makefile +++ b/Makefile @@ -10,10 +10,10 @@ change-deps: opam switch export opam.export setup-instructor: - cp src/haz3lweb/SchoolSettings_instructor.re src/haz3lweb/SchoolSettings.re + cp src/haz3lweb/ExerciseSettings_instructor.re src/haz3lweb/ExerciseSettings.re setup-student: - cp src/haz3lweb/SchoolSettings_student.re src/haz3lweb/SchoolSettings.re + cp src/haz3lweb/ExerciseSettings_student.re src/haz3lweb/ExerciseSettings.re dev-helper: dune build @src/fmt --auto-promote src --profile dev diff --git a/README.md b/README.md index df2f396d9a..3057e5f585 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Hazel ![Build Status](https://github.com/hazelgrove/hazel/actions/workflows/deploy_branches.yml/badge.svg) -[![Hazel Mascot](src/hazelweb/www/imgs/hazel-logo.png)](https://hazel.org) - Hazel is a live functional-programming environment rooted in the principles of type theory. You can find the relevant papers and more motivation at [the Hazel website](https://hazel.org/). -You can try Hazel online with either the -[trunk](https://hazel.org/build/trunk/index.html) or -[dev](https://hazel.org/build/dev/index.html) version. Note that the trunk -branch is updated infrequently and is currently almost two years behind! +You can try Hazel online: the +[dev](https://hazel.org/build/dev) branch is the main branch at the +moment. Every other branch that has been pushed to GitHub and successfully builds +can also be accessed at: + + `https://hazel.org/build/` @@ -26,13 +26,13 @@ installed, you can build Hazel by running the following commands. - `make dev` To view Hazel, you have to serve it, on localhost for development (you can't -run it from a `file:///` URL due to browser restrictions on web workers.) +run it from a `file:///` URL due to browser restrictions on e.g. web workers.) If you have `python3` on your path, you can use the Python server via `make serve`, then navigate to `http://0.0.0.0:8000/` in your browser. -Otherwise, run `make echo-html-dir` for the directory that needs to be served -using the server of your choice. +Otherwise, run `make echo-html-dir` which will echo the directory that needs +to be served using some other server of your choice. ### Long Version @@ -44,16 +44,20 @@ instructions contained in [INSTALL.md](INSTALL.md). ### From OCaml to ReasonML +Hazel is written in ReasonML, which is a syntactic sugar atop OCaml. This link lets you type OCaml and see what the corresponding ReasonML syntax is: . This is useful if you are trying to figure out the ReasonML syntax for something that you know the OCaml syntax for. +You can also convert between OCaml and ReasonML syntax at the terminal using +`refmt` at the terminal. See `refmt --help` for the details. + ### Suggested Extensions for VS Code -Most of our team uses VisualStudio Code to write code. If you use VS Code, here -are a few extensions that might be helpful. +Most of our team uses Visual Studio Code (VS Code) to write code. +If you use VS Code, here are a few extensions that might be helpful. - This extension provides full support for editing ReasonML source code and relevant tools: @@ -84,7 +88,7 @@ If you enjoy your Vim binding and Vim setup, the following may help you set up y If you use vim, I recommend you to switch to NeoVim since it has a better support for multi-thread, and thus less likely to block you when you are programming. -To set up the LSP(Language Server Protocal), you need to set up your Language Client for Neovim and Language Server for ocaml. +To set up the LSP (Language Server Protocol), you need to set up your Language Client for Neovim and Language Server for ocaml. - [ocaml-language-server](https://www.npmjs.com/package/ocaml-language-server) - [LanguageClient-neovim](https://github.com/autozimu/LanguageClient-neovim) @@ -107,8 +111,7 @@ nnoremap :call LanguageClient#textDocument_rename() ### Build System Details -Hazel is implemented in Reason (a dialect of OCaml) and is compiled to -Javascript for the web browser via the `js_of_ocaml` compiler. +Hazel is compiled to Javascript for the web browser via the `js_of_ocaml` compiler. Though `make` targets are provided as a convenience, they mostly translate to `dune` commands. @@ -130,7 +133,7 @@ The `make dev` and `make release` commands do three things: (`_build/default/src/hazelweb/www/hazel.js`) using `js_of_ocaml`. For a smoother dev experience, use `make watch` to automatically watch -for file changes. This will require installing `fswatch` (see INSTALL.md). +for file changes. This may require installing `fswatch` (see INSTALL.md). You can also run `make watch-release` to continuously build the release build (takes longer per build). @@ -167,6 +170,9 @@ existing OCaml projects. #### Printing You can print to the browser console using the standard `print_endline` function. This is probably the easiest method right now. +Most datatypes in the codebase have something like `[@deriving (show({with_path: false}), sexp, yojson)]` on them. This generates +helper functions for printing and serializing this data. For a type named `t`, the `show` function will be named `show`. Otherwise, +for a type named something else like `q`, it will be `show_q`. #### Source Maps `js_of_ocaml` does support source maps and has some other flags that might be useful. If you experiment with those and get them to work, please update this README with some notes. @@ -174,14 +180,6 @@ You can print to the browser console using the standard `print_endline` function #### Debug Mode If Hazel is hanging on load or when you perform certain actions, you can load into Debug Mode by appending `#debug` to the URL and reloading. From there, you have some buttons that will change settings or reset local storage. Refresh without the `#debug` flag and hopefully you can resolve the situation from there. -### Testing - -You can run all of the unit tests located in `src/hazelcore/test` by running `make test`. - -Unit tests are written using [ppx_expect](https://github.com/janestreet/ppx_expect/tree/master/example) and [ppx_inline_tests](https://github.com/janestreet/ppx_inline_test/tree/master/example). If you would like to adjust your expect tests to assert for the output that was last printed, run `make fix-test-answers`. - -If the inline test runner causes problems for you, you can likely resolve the issue by running `opam update` then `opam upgrade`. - ### Continuous Integration When you push your branch to the main `hazelgrove/hazel` repository, we diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c94c805f29..c8e4bee946 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -18,9 +18,11 @@ type t = | List(list(t)); // How to replace this function? -let rec constrains = (c: t, ty: HTyp.t): bool => - switch (c, ty) { - // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { +let rec constrains = (c: t, ty: Typ.t): bool => + switch ( + c, + Typ.weak_head_normalize(Builtins.ctx(Builtins.Pervasives.builtins), ty), + ) { | (Truth, _) | (Falsity, _) | (Hole, _) => true @@ -32,10 +34,110 @@ let rec constrains = (c: t, ty: HTyp.t): bool => | (String(_) | NotString(_), _) => false | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) - | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + // Treates sum as if it is left associative + | (InjL(c1), Sum(map)) => + switch (List.hd(map)) { + | (_, Some(ty1)) => constrains(c1, ty1) + | _ => false + } | (InjL(_), _) => false - | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(c2), Sum(map)) => + switch (List.tl(map)) { + | [] => false + | [(_, Some(ty2))] => constrains(c2, ty2) + | map' => constrains(c2, Sum(map')) + } | (InjR(_), _) => false | (List(c), ty) => List.fold_left((last, x) => last && constrains(x, ty), true, c) }; + +let rec or_constraints = (lst: list(t)): t => + switch (lst) { + | [] => failwith("should have at least one constraint") + | [xi] => xi + | [xi, ...xis] => Or(xi, or_constraints(xis)) + }; + +let rec dual = (c: t): t => + switch (c) { + | Truth => Falsity + | Falsity => Truth + | Hole => Hole + | Int(n) => NotInt(n) + | NotInt(n) => Int(n) + | Float(n) => NotFloat(n) + | NotFloat(n) => Float(n) + | String(n) => NotString(n) + | NotString(n) => String(n) + | And(c1, c2) => Or(dual(c1), dual(c2)) + | Or(c1, c2) => And(dual(c1), dual(c2)) + | InjL(c1) => Or(InjL(dual(c1)), InjR(Truth)) + | InjR(c2) => Or(InjR(dual(c2)), InjL(Truth)) + // Thought: generate all combinations of ways to dual the list (2^n - 1), and connect them with or + | List(l) => + let permutation = List.map(l' => List(l'), List.tl(permutate(l))); + // ``Or'' is associative, so I try to use this way to simplify it + or_constraints(permutation); + } +and permutate = (l: list(t)): list(list(t)) => + switch (l) { + | [] => [[]] + | [hd, ...tl] => + let result_tl = permutate(tl); + List.map(l' => [hd, ...l'], result_tl) + @ List.map(l' => [dual(hd), ...l'], result_tl); + }; + +/** substitute Truth for Hole */ +let rec truify = (c: t): t => + switch (c) { + | Hole => Truth + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(truify(c1), truify(c2)) + | Or(c1, c2) => Or(truify(c1), truify(c2)) + | InjL(c) => InjL(truify(c)) + | InjR(c) => InjR(truify(c)) + | List(l) => List.map(c => truify(c), l) + }; + +/** substitute Falsity for Hole */ +let rec falsify = (c: t): t => + switch (c) { + | Hole => Falsity + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(falsify(c1), falsify(c2)) + | Or(c1, c2) => Or(falsify(c1), falsify(c2)) + | InjL(c) => InjL(falsify(c)) + | InjR(c) => InjR(falsify(c)) + | List(l) => List.map(c => falsify(c), l) + }; + +let unwrapL = + fun + | InjL(c) => c + | _ => failwith("input can only be InjL(_)"); + +let unwrapR = + fun + | InjR(c) => c + | _ => failwith("input can only be InjR(_)"); + +let unwrap_list = + fun + | List(l) => l + | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file From 41e205275547bec4987c6cacaaf6f1d3fc34af80 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 15 Aug 2023 21:36:44 -0400 Subject: [PATCH 015/229] Ensured that the numbers must match to have recursive functions --- src/haz3lcore/dynamics/Elaborator.re | 1 - src/haz3lcore/statics/Statics.re | 5 +---- src/haz3lcore/statics/Term.re | 3 ++- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 937a8b90be..e6caed76d7 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -208,7 +208,6 @@ let rec dhexp_of_uexp = let* ddef = dhexp_of_uexp(m, def); let* dbody = dhexp_of_uexp(m, body); let+ ty_body = fixed_exp_typ(m, body); - //switch (Term.UPat.get_recursive_bindings(p)) { switch (Term.UExp.get_recursive_bindings(p, def)) { | None => /* not recursive */ diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 7fb94ee3f7..205df9d328 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -262,7 +262,7 @@ and uexp_to_info_map = | Let(p, def, body) => let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); let is_tuple_of_functions = - UPat.is_tuple_of_arrows(p) && UExp.is_tuple_of_functions(def); + Option.is_some(Term.UExp.get_recursive_bindings(p, def)); let (def, p_ana, m) = if (!is_tuple_of_functions) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; @@ -276,9 +276,6 @@ and uexp_to_info_map = let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_ana.ty), def, m); (def, p_ana, m); }; - // let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); - // let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; - // let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); add( ~self=Just(body.ty), diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index c3b2d0de52..7cbc26fa95 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -681,7 +681,7 @@ module UExp = { }; let get_fun_var = (pat: UPat.t, e: t) => - if (UPat.is_fun_var(pat) || UPat.is_var(pat) && is_fun(e)) { + if ((UPat.is_var(pat) || UPat.is_fun_var(pat)) && is_fun(e)) { UPat.get_var(pat); } else { None; @@ -724,6 +724,7 @@ module UExp = { | Seq(_) | Test(_) | Cons(_) + | ListConcat(_) | UnOp(_) | BinOp(_) | Match(_) From 7f2e3578906b33f872500938712bb67fbcc93677 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 15 Aug 2023 23:48:57 -0400 Subject: [PATCH 016/229] Annotations outside of the variables --- src/haz3lcore/statics/Statics.re | 3 +-- src/haz3lcore/statics/Term.re | 35 ++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 205df9d328..a00efbe964 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -49,8 +49,7 @@ let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => let extend_let_def_ctx = (ctx: Ctx.t, pat: UPat.t, pat_ctx: Ctx.t, def: UExp.t): Ctx.t => - // if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { - if (Option.is_some(UExp.get_recursive_bindings(pat, def))) { + if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { pat_ctx; } else { ctx; diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 7cbc26fa95..51047ac2e9 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -147,6 +147,26 @@ module UTyp = { List.filter_map(to_variant(ctx), uts), ); }; + + let rec get_typs = (typ: t) => { + switch (typ.term) { + | Parens(typ) => get_typs(typ) + | Tuple(typs) => Some(typs) + | Arrow(_) + | EmptyHole + | Invalid(_) + | MultiHole(_) + | Int + | Float + | Bool + | String + | List(_) + | Var(_) + | Constructor(_) + | Ap(_) + | Sum(_) => None + }; + }; }; module UTPat = { @@ -418,8 +438,19 @@ module UPat = { let rec get_pats = (pat: t) => { switch (pat.term) { - | Parens(pat) - | TypeAnn(pat, _) => get_pats(pat) + | Parens(pat) => get_pats(pat) + | TypeAnn(pat, typ) => + switch (get_pats(pat), UTyp.get_typs(typ)) { + | (Some(pats), Some(typs)) + when List.length(pats) == List.length(typs) => + let annotate_pat = (pat, typ: UTyp.t) => { + ids: pat.ids @ typ.ids, + term: TypeAnn(pat, typ), + }; + let annotated_pats = List.map2(annotate_pat, pats, typs); + Some(annotated_pats); + | _ => None + } | Tuple(pats) => Some(pats) | Var(_) | Invalid(_) From 47c190525804963b9aff63ae00c4cfb7ed88b8ff Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 16 Aug 2023 18:38:12 +0800 Subject: [PATCH 017/229] Ported `Incon.re` and `Sets.re`. --- src/haz3lcore/dynamics/Constraint.re | 6 +- src/haz3lcore/dynamics/Incon.re | 296 +++++++++++++++++++++------ src/haz3lcore/dynamics/Sets.re | 23 +++ 3 files changed, 265 insertions(+), 60 deletions(-) create mode 100644 src/haz3lcore/dynamics/Sets.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c8e4bee946..1388e2fde6 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -105,7 +105,7 @@ let rec truify = (c: t): t => | Or(c1, c2) => Or(truify(c1), truify(c2)) | InjL(c) => InjL(truify(c)) | InjR(c) => InjR(truify(c)) - | List(l) => List.map(c => truify(c), l) + | List(l) => List(List.map(c => truify(c), l)) }; /** substitute Falsity for Hole */ @@ -124,7 +124,7 @@ let rec falsify = (c: t): t => | Or(c1, c2) => Or(falsify(c1), falsify(c2)) | InjL(c) => InjL(falsify(c)) | InjR(c) => InjR(falsify(c)) - | List(l) => List.map(c => falsify(c), l) + | List(l) => List(List.map(c => falsify(c), l)) }; let unwrapL = @@ -140,4 +140,4 @@ let unwrapR = let unwrap_list = fun | List(l) => l - | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file + | _ => failwith("input can only be List([_, ..._])"); diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 2d403e1174..204d181cb6 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -1,64 +1,246 @@ -let rec matches = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (_, Var(_)) => true - | (_, Wild) => true - | (BoolLit(x), BoolLit(y)) => x == y - | (IntLit(x), IntLit(y)) => x == y - | (FloatLit(x), FloatLit(y)) => x == y - | (StringLit(x), StringLit(y)) => x == y - | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know if my algorithm is correct or not. - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => true - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) - | (_, _) => false +open Sets; + +let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { + let (int_set, not_int_list) = + List.fold_left( + ((int_set, not_int_list), xi: Constraint.t) => + switch (xi) { + | Int(n) => (IntSet.add(n, int_set), not_int_list) + | NotInt(n) => (int_set, [n, ...not_int_list]) + | _ => failwith("input can only be Int | NotInt") + }, + (IntSet.empty, []), + xis, + ); + if (IntSet.cardinal(int_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + IntSet.mem(n, int_set); + }, + false, + not_int_list, + ); }; +}; -let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (BoolLit(x), BoolLit(y)) => x != y - | (IntLit(x), IntLit(y)) => x != y - | (FloatLit(x), FloatLit(y)) => x != y - | (StringLit(x), StringLit(y)) => x != y - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => false - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) - | (Inj(_, side1, x), Inj(side2, y)) => - side1 != side2 || does_not_match(x, y) - | (_, _) => false +let is_inconsistent_float = (xis: list(Constraint.t)): bool => { + let (float_set, not_float_list) = + List.fold_left( + ((float_set, not_float_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (FloatSet.add(n, float_set), not_float_list) + | NotFloat(n) => (float_set, [n, ...not_float_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (FloatSet.empty, []), + xis, + ); + if (FloatSet.cardinal(float_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + FloatSet.mem(n, float_set); + }, + false, + not_float_list, + ); }; +}; -// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. -let indet_match = (e: DHExp.t, p: DHPat.t): bool => - !(matches(e, p) || does_not_match(e, p)); +let is_inconsistent_string = (xis: list(Constraint.t)): bool => { + let (string_set, not_string_list) = + List.fold_left( + ((string_set, not_string_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (StringSet.add(n, string_set), not_string_list) + | NotFloat(n) => (string_set, [n, ...not_string_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (StringSet.empty, []), + xis, + ); + if (StringSet.cardinal(string_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + StringSet.mem(n, string_set); + }, + false, + not_string_list, + ); + }; +}; -let rec is_val = (e: DHExp.t): bool => - switch (e) { - | BoolLit(_) - | IntLit(_) - | StringLit(_) - | Fun(_, _, _, _) - | ListLit(_, _, _, _, []) - | Tuple([]) => true - | ListLit(_, _, _, _, inner) - | Tuple(inner) => - List.fold_left((last_val, e) => last_val && is_val(e), true, inner) - | BinBoolOp(_, e1, e2) - | BinIntOp(_, e1, e2) - | BinFloatOp(_, e1, e2) - | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false - | Inj(_, _, e) => is_val(e) - | _ => false +let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => + switch (xis) { + | [] => false + | [xi, ...xis'] => + switch (xi) { + | Truth => is_inconsistent(~may, xis') + | Falsity => true + | Hole => may ? true : is_inconsistent(~may, xis') + | And(xi1, xi2) => is_inconsistent(~may, [xi1, xi2, ...xis']) + | Or(xi1, xi2) => + is_inconsistent(~may, [xi1, ...xis']) + && is_inconsistent(~may, [xi2, ...xis']) + | InjL(_) => + if (List.exists( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + ) + ) { + | (injLs, []) => + let unwrap = List.map(Constraint.unwrapL, injLs); + is_inconsistent(~may, unwrap); + | (injLs, other) => is_inconsistent(~may, other @ injLs) + }; + } + | InjR(_) => + if (List.exists( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + ) + ) { + | (injRs, []) => + let unwrap = List.map(Constraint.unwrapR, injRs); + is_inconsistent(~may, unwrap); + | (injRs, other) => is_inconsistent(~may, other @ injRs) + }; + } + | Int(_) + | NotInt(_) => + switch ( + List.partition( + fun + | Constraint.Int(_) + | NotInt(_) => true + | _ => false, + xis, + ) + ) { + | (ns, []) => is_inconsistent_nums(ns) + | (ns, other) => is_inconsistent(~may, other @ ns) + } + | Float(_) + | NotFloat(_) => + switch ( + List.partition( + fun + | Constraint.Float(_) + | NotFloat(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_float(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + | String(_) + | NotString(_) => + switch ( + List.partition( + fun + | Constraint.String(_) + | NotString(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_string(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + /* + * Thoughts for porting the Pair judgment to list: + * Two list constraints are automatically inconsistent if they have different length. + * So we first find maximum and minimum list lengths, and determine if they are the same. + * If so, we rearrange them in item-first order, and check each of them. + */ + | List(_) => + switch ( + List.partition( + fun + | Constraint.List(_) => true + | _ => false, + xis, + ) + ) { + | (lists, []) => + let lengths = + List.map(x => List.length(Constraint.unwrap_list(x)), lists); + // check if all lengths are equal + // This could be done with exceptions, but I found nothing related on ReasonML website. + let all_lengths_are_equal = + List.for_all(x => x == List.hd(lengths), List.tl(lengths)); + if (all_lengths_are_equal) { + let order_by_index = + List.fold_left( + // ordered_by_index: list(list(t)); item: packed version of list(t) + (ordered_by_index, lst) => + List.map2( + // We need a function that maps `(list(t), t)` to list(list(t) + (old_list, item) => [item, ...old_list], + ordered_by_index, + Constraint.unwrap_list(lst), + ), + // Initial version of empty list, in list(list(t)) + List.map(x => [x], Constraint.unwrap_list(List.hd(lists))), + // Rest of items + List.tl(lists), + ); + // Check if there are inconsistency in each element + List.fold_left( + (previous, item) => previous || is_inconsistent(~may, item), + may, + order_by_index, + ); + } else { + true; // Automatically inconsistent + }; + | (lists, other) => is_inconsistent(~may, other @ lists) + } + } }; -let rec is_indet = (e: DHExp.t): bool => - switch (e) { - | EmptyHole(_, _) => true - | NonEmptyHole(_, _, _, e) => is_final(e) - | _ => false - } -and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); +let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => + is_inconsistent( + ~may=false, + Constraint.[And(truify(xi_cur), dual(falsify(xi_pre)))], + ); + +let is_exhaustive = (xi: Constraint.t): bool => + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file diff --git a/src/haz3lcore/dynamics/Sets.re b/src/haz3lcore/dynamics/Sets.re new file mode 100644 index 0000000000..67b6099709 --- /dev/null +++ b/src/haz3lcore/dynamics/Sets.re @@ -0,0 +1,23 @@ +module IntSet = + Set.Make({ + type t = int; + let compare = compare; + }); + +module BoolSet = + Set.Make({ + type t = bool; + let compare = compare; + }); + +module FloatSet = + Set.Make({ + type t = float; + let compare = compare; + }); + +module StringSet = + Set.Make({ + type t = float; + let compare = compare; + }); From 51cd9825e17cbf4b6b4e009365aa7ac7981bf014 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 22 Aug 2023 05:43:00 -0400 Subject: [PATCH 018/229] Statics.is_recursive + some cast bug fixes --- src/haz3lcore/dynamics/Elaborator.re | 69 ++++---- src/haz3lcore/statics/Statics.re | 49 ++++-- src/haz3lcore/statics/Term.re | 229 +++++++-------------------- 3 files changed, 135 insertions(+), 212 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index e6caed76d7..ee7e91aff5 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -207,36 +207,47 @@ let rec dhexp_of_uexp = let* dp = dhpat_of_upat(m, p); let* ddef = dhexp_of_uexp(m, def); let* dbody = dhexp_of_uexp(m, body); - let+ ty_body = fixed_exp_typ(m, body); - switch (Term.UExp.get_recursive_bindings(p, def)) { - | None => + let* ty_body = fixed_exp_typ(m, body); + let+ ty_p = fixed_pat_typ(m, p); + if (!Statics.is_recursive(ctx, p, def, ty_p)) { /* not recursive */ - DHExp.Let(dp, add_name(Term.UPat.get_var(p), ddef), dbody) - | Some([f]) => - /* simple recursion */ - Let(dp, FixF(f, ty_body, add_name(Some(f), ddef)), dbody) - | Some(fs) => - /* mutual recursion */ - let ddef = - switch (ddef) { - | Tuple(a) => - DHExp.Tuple(List.map2(s => add_name(Some(s)), fs, a)) - | _ => ddef - }; - let uniq_id = List.nth(def.ids, 0); - let self_id = "__mutual__" ++ string_of_int(uniq_id); - let self_var = DHExp.BoundVar(self_id); - let (_, substituted_def) = - fs - |> List.fold_left( - ((i, ddef), f) => { - let ddef = - Substitution.subst_var(DHExp.Prj(self_var, i), f, ddef); - (i + 1, ddef); - }, - (0, ddef), - ); - Let(dp, FixF(self_id, ty_body, substituted_def), dbody); + DHExp.Let( + dp, + add_name(Term.UPat.get_var(p), ddef), + dbody, + ); + } else { + switch (Term.UPat.get_bindings(p) |> Option.get) { + | [f] => + /* simple recursion */ + Let(dp, FixF(f, ty_body, add_name(Some(f), ddef)), dbody) + | fs => + /* mutual recursion */ + let ddef = + switch (ddef) { + | Tuple(a) => + DHExp.Tuple(List.map2(s => add_name(Some(s)), fs, a)) + | _ => ddef + }; + let uniq_id = List.nth(def.ids, 0); + let self_id = "__mutual__" ++ string_of_int(uniq_id); + let self_var = DHExp.BoundVar(self_id); + let (_, substituted_def) = + fs + |> List.fold_left( + ((i, ddef), f) => { + let ddef = + Substitution.subst_var( + DHExp.Prj(self_var, i), + f, + ddef, + ); + (i + 1, ddef); + }, + (0, ddef), + ); + Let(dp, FixF(self_id, ty_body, substituted_def), dbody); + }; }; | Ap(fn, arg) => let* c_fn = dhexp_of_uexp(m, fn); diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index a00efbe964..9339a981f8 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -47,13 +47,27 @@ let map_m = (f, xs, m: Map.t) => let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => ids |> List.fold_left((m, id) => Id.Map.add(id, info, m), m); -let extend_let_def_ctx = - (ctx: Ctx.t, pat: UPat.t, pat_ctx: Ctx.t, def: UExp.t): Ctx.t => - if (UPat.is_tuple_of_arrows(pat) && UExp.is_tuple_of_functions(def)) { - pat_ctx; - } else { - ctx; +let is_recursive = (ctx, p, def, syn: Typ.t) => { + switch (Term.UPat.get_num_of_vars(p), Term.UExp.get_num_of_functions(def)) { + | (Some(num_vars), Some(num_fns)) + when num_vars != 0 && num_vars == num_fns => + switch (Typ.weak_head_normalize(ctx, syn)) { + | Unknown(_) => true + | Arrow(_) when num_vars == 1 => true + | Prod(syns) when List.length(syns) == num_vars => + syns + |> List.for_all(syn => + switch (Typ.weak_head_normalize(ctx, syn)) { + | Unknown(_) + | Arrow(_) => true + | _ => false + } + ) + | _ => false + } + | _ => false }; +}; let typ_exp_binop_bin_int: UExp.op_bin_int => Typ.t = fun @@ -260,10 +274,8 @@ and uexp_to_info_map = ); | Let(p, def, body) => let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); - let is_tuple_of_functions = - Option.is_some(Term.UExp.get_recursive_bindings(p, def)); let (def, p_ana, m) = - if (!is_tuple_of_functions) { + if (!is_recursive(ctx, p, def, p_syn.ty)) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); @@ -272,7 +284,24 @@ and uexp_to_info_map = let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); - let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_ana.ty), def, m); + // let (def_base2, m) = + // go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); + // let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { + // print_endline(Typ.show(ty_fn1)); + // print_endline(Typ.show(ty_fn2)); + // print_endline("=========="); + // Typ.eq(ty_fn1, ty_fn2) ? ty_p : ty_fn1; + // }; + // let ana = + // switch ((def_base.ty, def_base2.ty), p_syn.ty) { + // | ((Prod(ty_fns1), Prod(ty_fns2)), Prod(ty_ps)) => + // let tys = + // List.map2(ana_ty_fn, List.combine(ty_fns1, ty_fns2), ty_ps); + // Typ.Prod(tys); + // | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) + // }; + // let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(ana), def, m); + let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); (def, p_ana, m); }; let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 51047ac2e9..be84040225 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -87,26 +87,6 @@ module UTyp = { | Parens => "Parenthesized type" | Ap => "Constructor application"; - let rec is_arrow = (typ: t) => { - switch (typ.term) { - | Parens(typ) => is_arrow(typ) - | Arrow(_) - | EmptyHole => true - | Invalid(_) - | MultiHole(_) - | Int - | Float - | Bool - | String - | List(_) - | Tuple(_) - | Var(_) - | Constructor(_) - | Ap(_) - | Sum(_) => false - }; - }; - /* Converts a syntactic type into a semantic type */ let rec to_typ: (Ctx.t, t) => Typ.t = (ctx, utyp) => @@ -147,26 +127,6 @@ module UTyp = { List.filter_map(to_variant(ctx), uts), ); }; - - let rec get_typs = (typ: t) => { - switch (typ.term) { - | Parens(typ) => get_typs(typ) - | Tuple(typs) => Some(typs) - | Arrow(_) - | EmptyHole - | Invalid(_) - | MultiHole(_) - | Int - | Float - | Bool - | String - | List(_) - | Var(_) - | Constructor(_) - | Ap(_) - | Sum(_) => None - }; - }; }; module UTPat = { @@ -279,11 +239,11 @@ module UPat = { | Ap => "Constructor application" | TypeAnn => "Annotation"; - let rec is_var = (pat: t) => { + let rec get_var = (pat: t) => { switch (pat.term) { - | Parens(pat) => is_var(pat) - | Var(_) => true - | TypeAnn(_) + | Parens(pat) + | TypeAnn(pat, _) => get_var(pat) + | Var(x) => Some(x) | Invalid(_) | EmptyHole | MultiHole(_) @@ -297,14 +257,21 @@ module UPat = { | Cons(_, _) | Tuple(_) | Constructor(_) - | Ap(_) => false + | Ap(_) => None }; }; - let rec is_fun_var = (pat: t) => { + let ctr_name = (p: t): option(Constructor.t) => + switch (p.term) { + | Constructor(name) => Some(name) + | _ => None + }; + + let rec is_var = (pat: t) => { switch (pat.term) { - | Parens(pat) => is_fun_var(pat) - | TypeAnn(pat, typ) => is_var(pat) && UTyp.is_arrow(typ) + | Parens(pat) + | TypeAnn(pat, _) => is_var(pat) + | Var(_) => true | Invalid(_) | EmptyHole | MultiHole(_) @@ -316,21 +283,19 @@ module UPat = { | Triv | ListLit(_) | Cons(_, _) - | Var(_) | Tuple(_) | Constructor(_) | Ap(_) => false }; }; - let rec is_tuple_of_arrows = (pat: t) => + let rec is_tuple_of_vars = (pat: t) => is_var(pat) - || is_fun_var(pat) || ( switch (pat.term) { - | Parens(pat) => is_tuple_of_arrows(pat) - | Tuple(pats) => - pats |> List.for_all(pat => is_var(pat) || is_fun_var(pat)) + | Parens(pat) + | TypeAnn(pat, _) => is_tuple_of_vars(pat) + | Tuple(pats) => pats |> List.for_all(pat => is_var(pat)) | Invalid(_) | EmptyHole | MultiHole(_) @@ -343,73 +308,50 @@ module UPat = { | ListLit(_) | Cons(_, _) | Var(_) - | TypeAnn(_) | Constructor(_) | Ap(_) => false } ); - let rec get_var = (pat: t) => { - switch (pat.term) { - | Parens(pat) - | TypeAnn(pat, _) => get_var(pat) - | Var(x) => Some(x) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Wild - | Int(_) - | Float(_) - | Bool(_) - | String(_) - | Triv - | ListLit(_) - | Cons(_, _) - | Tuple(_) - | Constructor(_) - | Ap(_) => None - }; - }; - - let rec get_fun_var = (pat: t) => { - switch (pat.term) { - | Parens(pat) => get_fun_var(pat) - | TypeAnn(pat, typ) => - if (UTyp.is_arrow(typ)) { - get_var(pat) |> Option.map(var => var); - } else { - None; - } - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Wild - | Int(_) - | Float(_) - | Bool(_) - | String(_) - | Triv - | ListLit(_) - | Cons(_, _) - | Var(_) - | Tuple(_) - | Constructor(_) - | Ap(_) => None + let rec get_num_of_vars = (pat: t) => + if (is_var(pat)) { + Some(1); + } else { + switch (pat.term) { + | Parens(pat) + | TypeAnn(pat, _) => get_num_of_vars(pat) + | Tuple(pats) => + is_tuple_of_vars(pat) ? Some(List.length(pats)) : None + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Wild + | Int(_) + | Float(_) + | Bool(_) + | String(_) + | Triv + | ListLit(_) + | Cons(_, _) + | Var(_) + | Constructor(_) + | Ap(_) => None + }; }; - }; - let rec get_recursive_bindings = (pat: t) => { - switch (get_fun_var(pat)) { + let rec get_bindings = (pat: t) => + switch (get_var(pat)) { | Some(x) => Some([x]) | None => switch (pat.term) { - | Parens(pat) => get_recursive_bindings(pat) + | Parens(pat) + | TypeAnn(pat, _) => get_bindings(pat) | Tuple(pats) => - let fun_vars = pats |> List.map(get_fun_var); - if (List.exists(Option.is_none, fun_vars)) { + let vars = pats |> List.map(get_var); + if (List.exists(Option.is_none, vars)) { None; } else { - Some(List.map(Option.get, fun_vars)); + Some(List.map(Option.get, vars)); }; | Invalid(_) | EmptyHole @@ -423,51 +365,10 @@ module UPat = { | ListLit(_) | Cons(_, _) | Var(_) - | TypeAnn(_) | Constructor(_) | Ap(_) => None } }; - }; - - let ctr_name = (p: t): option(Constructor.t) => - switch (p.term) { - | Constructor(name) => Some(name) - | _ => None - }; - - let rec get_pats = (pat: t) => { - switch (pat.term) { - | Parens(pat) => get_pats(pat) - | TypeAnn(pat, typ) => - switch (get_pats(pat), UTyp.get_typs(typ)) { - | (Some(pats), Some(typs)) - when List.length(pats) == List.length(typs) => - let annotate_pat = (pat, typ: UTyp.t) => { - ids: pat.ids @ typ.ids, - term: TypeAnn(pat, typ), - }; - let annotated_pats = List.map2(annotate_pat, pats, typs); - Some(annotated_pats); - | _ => None - } - | Tuple(pats) => Some(pats) - | Var(_) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Wild - | Int(_) - | Float(_) - | Bool(_) - | String(_) - | Triv - | ListLit(_) - | Cons(_, _) - | Constructor(_) - | Ap(_) => None - }; - }; }; module UExp = { @@ -711,30 +612,13 @@ module UExp = { }; }; - let get_fun_var = (pat: UPat.t, e: t) => - if ((UPat.is_var(pat) || UPat.is_fun_var(pat)) && is_fun(e)) { - UPat.get_var(pat); + let rec get_num_of_functions = (e: t) => + if (is_fun(e)) { + Some(1); } else { - None; - }; - - let rec get_recursive_bindings = (pat: UPat.t, e: t) => { - switch (get_fun_var(pat, e)) { - | Some(x) => Some([x]) - | None => switch (e.term) { - | Parens(e) => get_recursive_bindings(pat, e) - | Tuple(es) => - switch (UPat.get_pats(pat)) { - | Some(pats) when List.length(pats) == List.length(es) => - let fun_vars = List.map2(get_fun_var, pats, es); - if (List.exists(Option.is_none, fun_vars)) { - None; - } else { - Some(List.map(Option.get, fun_vars)); - }; - | _ => None - } + | Parens(e) => get_num_of_functions(e) + | Tuple(es) => is_tuple_of_functions(e) ? Some(List.length(es)) : None | Invalid(_) | EmptyHole | MultiHole(_) @@ -760,9 +644,8 @@ module UExp = { | BinOp(_) | Match(_) | Constructor(_) => None - } + }; }; - }; }; // TODO(d): consider just folding this into UExp From 80e15bc002e93ef97c586ab4bf236ea7cae859e5 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 23 Aug 2023 20:13:11 +0800 Subject: [PATCH 019/229] Fixed dependency problem. --- opam.export | 96 +++++++++++++++++---------------- src/haz3lcore/dynamics/Incon.re | 2 +- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/opam.export b/opam.export index 98f8552d3a..9cf1612dd5 100644 --- a/opam.export +++ b/opam.export @@ -2,20 +2,20 @@ opam-version: "2.0" compiler: ["ocaml-base-compiler.5.0.0"] roots: [ "incr_dom.v0.15.1" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" - "merlin.4.8-500" + "merlin.4.9-500" "ocaml-base-compiler.5.0.0" - "ocaml-lsp-server.1.15.1-5.0" - "ocamlformat.0.25.1" - "omd.1.3.2" + "ocaml-lsp-server.1.16.2" + "ocamlformat.0.26.0" + "omd.2.0.0~alpha4" "ppx_deriving.5.2.1" "ppx_yojson_conv.v0.15.1" "ptmap.2.0.5" - "reason.3.8.2" - "tezt.3.0.0" + "reason.3.9.0" + "tezt.3.1.1" "unionFind.20220122" - "utop.2.11.0" + "utop.2.13.1" ] installed: [ "abstract_algebra.v0.15.0" @@ -36,24 +36,26 @@ installed: [ "bigstringaf.0.9.1" "bin_prot.v0.15.0" "camlp-streams.5.0.1" - "chrome-trace.3.7.0" - "cmdliner.1.1.1" + "chrome-trace.3.10.0" + "cmdliner.1.2.0" + "conf-autoconf.0.1" + "conf-which.1" "core.v0.15.1" "core_kernel.v0.15.0" "cppo.1.6.9" - "csexp.1.5.1" + "csexp.1.5.2" "cstruct.6.2.0" - "dot-merlin-reader.4.6" - "dune.3.7.0" - "dune-build-info.3.7.0" - "dune-configurator.3.7.0" - "dune-rpc.3.6.2" - "dyn.3.6.2" + "dot-merlin-reader.4.9" + "dune.3.10.0" + "dune-build-info.3.10.0" + "dune-configurator.3.10.0" + "dune-rpc.3.10.0" + "dyn.3.10.0" "either.1.0.0" "ezjsonm.1.3.0" - "fiber.3.6.2" + "fiber.3.7.0" "fieldslib.v0.15.0" - "fix.20220121" + "fix.20230505" "fmt.0.9.0" "fpath.0.7.3" "gen.1.1" @@ -65,24 +67,24 @@ installed: [ "incremental.v0.15.0" "int_repr.v0.15.0" "jane-street-headers.v0.15.0" - "js_of_ocaml.4.1.0" - "js_of_ocaml-compiler.4.1.0" - "js_of_ocaml-ppx.4.1.0" + "js_of_ocaml.5.4.0" + "js_of_ocaml-compiler.5.4.0" + "js_of_ocaml-ppx.5.4.0" "jsonm.1.0.2" "jst-config.v0.15.1" - "lambda-term.3.3.1" + "lambda-term.3.3.2" "lambdasoup.1.0.0" "logs.0.7.0" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" "lwt_react.1.2.0" "markup.1.0.3" - "menhir.20220210" - "menhirLib.20220210" - "menhirSdk.20220210" - "merlin.4.8-500" + "menhir.20230608" + "menhirLib.20230608" + "menhirSdk.20230608" + "merlin.4.9-500" "merlin-extend.0.6.1" - "merlin-lib.4.8-500" + "merlin-lib.4.9-500" "mew.0.1.0" "mew_vi.0.5.0" "num.1.4" @@ -90,28 +92,28 @@ installed: [ "ocaml-base-compiler.5.0.0" "ocaml-compiler-libs.v0.12.4" "ocaml-config.3" - "ocaml-lsp-server.1.15.1-5.0" + "ocaml-lsp-server.1.16.2" "ocaml-options-vanilla.1" "ocaml-syntax-shims.1.0.0" "ocaml-version.3.6.1" "ocamlbuild.0.14.2" - "ocamlc-loc.3.6.2" + "ocamlc-loc.3.10.0" "ocamlfind.1.9.6" - "ocamlformat.0.25.1" - "ocamlformat-lib.0.25.1" - "ocamlformat-rpc-lib.0.25.1" + "ocamlformat.0.26.0" + "ocamlformat-lib.0.26.0" + "ocamlformat-rpc-lib.0.26.0" "ocp-indent.1.8.1" "ocplib-endian.1.2" "octavius.1.2.2" "odoc-parser.2.0.0" "ojs.1.1.2" - "omd.1.3.2" - "ordering.3.6.2" + "omd.2.0.0~alpha4" + "ordering.3.10.0" "parsexp.v0.15.0" "pp.1.1.2" "ppx_assert.v0.15.0" "ppx_base.v0.15.0" - "ppx_bench.v0.15.0" + "ppx_bench.v0.15.1" "ppx_bin_prot.v0.15.0" "ppx_cold.v0.15.0" "ppx_compare.v0.15.0" @@ -126,7 +128,7 @@ installed: [ "ppx_hash.v0.15.0" "ppx_here.v0.15.0" "ppx_ignore_instrumentation.v0.15.0" - "ppx_inline_test.v0.15.0" + "ppx_inline_test.v0.15.1" "ppx_jane.v0.15.0" "ppx_js_style.v0.15.0" "ppx_let.v0.15.0" @@ -145,14 +147,14 @@ installed: [ "ppx_variants_conv.v0.15.0" "ppx_yojson_conv.v0.15.1" "ppx_yojson_conv_lib.v0.15.0" - "ppxlib.0.28.0" + "ppxlib.0.30.0" "protocol_version_header.v0.15.0" "ptmap.2.0.5" "re.1.10.4" "react.1.2.2" - "reason.3.8.2" + "reason.3.9.0" "result.1.5" - "sedlex.3.1" + "sedlex.3.2" "seq.base" "sexplib.v0.15.1" "sexplib0.v0.15.1" @@ -161,9 +163,9 @@ installed: [ "stdcompat.19" "stdio.v0.15.0" "stdlib-shims.0.3.0" - "stdune.3.6.2" + "stdune.3.10.0" "stringext.1.6.0" - "tezt.3.0.0" + "tezt.3.1.1" "time_now.v0.15.0" "topkg.1.0.7" "trie.1.0.0" @@ -173,16 +175,16 @@ installed: [ "unionFind.20220122" "uri.4.2.0" "uri-sexp.4.2.0" - "utop.2.11.0" + "utop.2.13.1" "uucp.15.0.0" "uunf.15.0.0" "uuseg.15.0.0" "uutf.1.0.3" "variantslib.v0.15.0" "virtual_dom.v0.15.1" - "xdg.3.7.0" - "yojson.2.0.2" - "zed.3.2.1" + "xdg.3.10.0" + "yojson.2.1.0" + "zed.3.2.3" ] pinned: [ "async_js.v0.15.1" diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 204d181cb6..8b9bd7b02d 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -243,4 +243,4 @@ let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => ); let is_exhaustive = (xi: Constraint.t): bool => - is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); From 1b51f5caa065ae7543acf0da7132abd6f47107b2 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 24 Aug 2023 03:37:45 -0400 Subject: [PATCH 020/229] Let mode consistent with context type --- src/haz3lcore/statics/Statics.re | 35 +++++++++++++++----------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 9339a981f8..79361f60c5 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -276,7 +276,7 @@ and uexp_to_info_map = let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); let (def, p_ana, m) = if (!is_recursive(ctx, p, def, p_syn.ty)) { - let (def, m) = go(~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + let (def, m) = go(~mode=Ana(p_syn.ty), def, m); let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); (def, p_ana, m); @@ -284,24 +284,21 @@ and uexp_to_info_map = let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); - // let (def_base2, m) = - // go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); - // let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { - // print_endline(Typ.show(ty_fn1)); - // print_endline(Typ.show(ty_fn2)); - // print_endline("=========="); - // Typ.eq(ty_fn1, ty_fn2) ? ty_p : ty_fn1; - // }; - // let ana = - // switch ((def_base.ty, def_base2.ty), p_syn.ty) { - // | ((Prod(ty_fns1), Prod(ty_fns2)), Prod(ty_ps)) => - // let tys = - // List.map2(ana_ty_fn, List.combine(ty_fns1, ty_fns2), ty_ps); - // Typ.Prod(tys); - // | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) - // }; - // let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(ana), def, m); - let (def, m) = go'(~ctx=p_ana.ctx, ~mode=Ana(p_syn.ty), def, m); + let def_ctx = p_ana.ctx; + let (def_base2, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); + let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { + ty_p == Typ.Unknown(SynSwitch) && !Typ.eq(ty_fn1, ty_fn2) + ? ty_fn1 : ty_p; + }; + let ana = + switch ((def_base.ty, def_base2.ty), p_syn.ty) { + | ((Prod(ty_fns1), Prod(ty_fns2)), Prod(ty_ps)) => + let tys = + List.map2(ana_ty_fn, List.combine(ty_fns1, ty_fns2), ty_ps); + Typ.Prod(tys); + | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) + }; + let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(ana), def, m); (def, p_ana, m); }; let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); From 0bb43a626477d57041badc827530e9105b285fb2 Mon Sep 17 00:00:00 2001 From: disconcision Date: Thu, 9 Feb 2023 15:03:43 -0500 Subject: [PATCH 021/229] merge in poly-adt --- src/haz3lcore/dynamics/DH.re | 16 ++++- src/haz3lcore/dynamics/Elaborator.re | 24 ++++++- src/haz3lcore/dynamics/Evaluator.re | 44 +++++++++--- src/haz3lcore/dynamics/EvaluatorPost.re | 19 +++++ src/haz3lcore/dynamics/Substitution.re | 2 + src/haz3lcore/lang/Form.re | 5 ++ src/haz3lcore/statics/Kind.re | 5 +- src/haz3lcore/statics/MakeTerm.re | 19 ++++- src/haz3lcore/statics/Statics.re | 66 ++++++++++++++++- src/haz3lcore/statics/Term.re | 63 ++++++++++++++--- src/haz3lcore/statics/TermBase.re | 74 ++++++++++++++++++++ src/haz3lcore/statics/TypBase.re | 57 +++++++++++++++ src/haz3lcore/zipper/EditorUtil.re | 2 + src/haz3lweb/view/CursorInspector.re | 11 ++- src/haz3lweb/view/LangDoc.re | 31 ++++++++ src/haz3lweb/view/Type.re | 11 ++- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 14 +++- src/haz3lweb/view/dhcode/layout/HTypDoc.re | 18 ++++- 18 files changed, 446 insertions(+), 35 deletions(-) diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index 61d7483930..72f08d00a6 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -15,6 +15,8 @@ module rec DHExp: { | Let(DHPat.t, t, t) | FixF(Var.t, Typ.t, t) | Fun(DHPat.t, Typ.t, t, option(Var.t)) + | TypFun(Term.UTPat.t, t) + | TypAp(t, Typ.t) | Ap(t, t) | ApBuiltin(string, list(t)) | TestLit(KeywordID.t) @@ -69,6 +71,8 @@ module rec DHExp: { | Let(DHPat.t, t, t) | FixF(Var.t, Typ.t, t) | Fun(DHPat.t, Typ.t, t, option(Var.t)) + | TypFun(Term.UTPat.t, t) + | TypAp(t, Typ.t) | Ap(t, t) | ApBuiltin(string, list(t)) | TestLit(KeywordID.t) @@ -107,8 +111,10 @@ module rec DHExp: { | Let(_, _, _) => "Let" | FixF(_, _, _) => "FixF" | Fun(_, _, _, _) => "Fun" + | TypFun(_) => "TypFun" | Closure(_, _) => "Closure" | Ap(_, _) => "Ap" + | TypAp(_) => "TypAp" | ApBuiltin(_, _) => "ApBuiltin" | TestLit(_) => "TestLit" | BoolLit(_) => "BoolLit" @@ -139,7 +145,7 @@ module rec DHExp: { | xs => Tuple(xs); let cast = (d: t, t1: Typ.t, t2: Typ.t): t => - if (Typ.eq(t1, t2) || t2 == Unknown(SynSwitch)) { + if (Typ.eq_syntactic(t1, t2) || t2 == Unknown(SynSwitch)) { d; } else { Cast(d, t1, t2); @@ -163,7 +169,9 @@ module rec DHExp: { | Let(dp, b, c) => Let(dp, strip_casts(b), strip_casts(c)) | FixF(a, b, c) => FixF(a, b, strip_casts(c)) | Fun(a, b, c, d) => Fun(a, b, strip_casts(c), d) + | TypFun(a, b) => TypFun(a, strip_casts(b)) | Ap(a, b) => Ap(strip_casts(a), strip_casts(b)) + | TypAp(a, b) => TypAp(strip_casts(a), b) | ApBuiltin(fn, args) => ApBuiltin(fn, List.map(strip_casts, args)) | BinBoolOp(a, b, c) => BinBoolOp(a, strip_casts(b), strip_casts(c)) | BinIntOp(a, b, c) => BinIntOp(a, strip_casts(b), strip_casts(c)) @@ -216,6 +224,10 @@ module rec DHExp: { f1 == f2 && ty1 == ty2 && fast_equal(d1, d2) | (Fun(dp1, ty1, d1, s1), Fun(dp2, ty2, d2, s2)) => dp1 == dp2 && ty1 == ty2 && fast_equal(d1, d2) && s1 == s2 + | (TypFun(_tpat1, d1), TypFun(_tpat2, d2)) => + // TODO (poly) + fast_equal(d1, d2) + | (TypAp(d1, ty1), TypAp(d2, ty2)) => fast_equal(d1, d2) && ty1 == ty2 | (Ap(d11, d21), Ap(d12, d22)) | (Cons(d11, d21), Cons(d12, d22)) => fast_equal(d11, d12) && fast_equal(d21, d22) @@ -250,7 +262,9 @@ module rec DHExp: { | (Let(_), _) | (FixF(_), _) | (Fun(_), _) + | (TypFun(_), _) | (Ap(_), _) + | (TypAp(_), _) | (ApBuiltin(_), _) | (Cons(_), _) | (ListConcat(_), _) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 9911b37710..ef76735da6 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -53,6 +53,16 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => let (_, ana_out) = Typ.matched_arrow(ana_ty); let (self_in, _) = Typ.matched_arrow(self_ty); DHExp.cast(d, Arrow(self_in, ana_out), ana_ty); + | TypFun(_) => + switch (ana_ty) { + | Unknown(prov) => + DHExp.cast( + d, + Forall({item: Unknown(prov), name: "grounded_forall"}), + ana_ty, + ) + | _ => d + } | Tuple(ds) => switch (ana_ty) { | Unknown(prov) => @@ -63,7 +73,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | Ap(Constructor(_), _) | Constructor(_) => switch (ana_ty, self_ty) { - | (Unknown(prov), Rec(_, Sum(_))) + | (Unknown(prov), Rec({item: Sum(_), _})) | (Unknown(prov), Sum(_)) => DHExp.cast(d, self_ty, Unknown(prov)) | _ => d } @@ -97,7 +107,10 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | BinIntOp(_) | BinFloatOp(_) | BinStringOp(_) - | TestLit(_) => DHExp.cast(d, self_ty, ana_ty) + | TestLit(_) + | TypAp(_) => + // TODO: check with andrew + DHExp.cast(d, self_ty, ana_ty) }; }; @@ -145,6 +158,10 @@ let rec dhexp_of_uexp = let* d1 = dhexp_of_uexp(m, body); let+ ty = fixed_pat_typ(m, p); DHExp.Fun(dp, ty, d1, None); + | TypFun(tpat, body) => + // TODO (typfun) + let+ d1 = dhexp_of_uexp(m, body); + DHExp.TypFun(tpat, d1); | Tuple(es) => let+ ds = es |> List.map(dhexp_of_uexp(m)) |> OptUtil.sequence; DHExp.Tuple(ds); @@ -241,6 +258,9 @@ let rec dhexp_of_uexp = let* c_fn = dhexp_of_uexp(m, fn); let+ c_arg = dhexp_of_uexp(m, arg); DHExp.Ap(c_fn, c_arg); + | TypAp(fn, uty_arg) => + let+ d_fn = dhexp_of_uexp(m, fn); + DHExp.TypAp(d_fn, Term.UTyp.to_typ(ctx, uty_arg)); | If(scrut, e1, e2) => let* d_scrut = dhexp_of_uexp(m, scrut); let* d1 = dhexp_of_uexp(m, e1); diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 529ca04260..17568ca412 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -23,6 +23,11 @@ let const_unknown: 'a => Typ.t = _ => Unknown(Internal); let grounded_Arrow = NotGroundOrHole(Arrow(Unknown(Internal), Unknown(Internal))); +// TODO (typfun): Maybe the Forall should allow a hole in the variable position? +let grounded_Forall = + NotGroundOrHole( + Forall({item: Unknown(Internal), name: "grounded_forall"}), + ); let grounded_Prod = length => NotGroundOrHole(Prod(ListUtil.replicate(length, Typ.Unknown(Internal)))); let grounded_Sum = (sm: Typ.sum_map): ground_cases => { @@ -61,6 +66,7 @@ let rec ground_cases_of = (ty: Typ.t): ground_cases => { | Sum(sm) => sm |> ConstructorMap.is_ground(is_ground_arg) ? Ground : grounded_Sum(sm) | Arrow(_, _) => grounded_Arrow + | Forall(_) => grounded_Forall | List(_) => grounded_List }; }; @@ -177,8 +183,8 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | None => DoesNotMatch } - | (Ap(_, _), Cast(d, Sum(_) | Rec(_, Sum(_)), Unknown(_))) - | (Ap(_, _), Cast(d, Unknown(_), Sum(_) | Rec(_, Sum(_)))) => + | (Ap(_, _), Cast(d, Sum(_) | Rec({item: Sum(_), _}), Unknown(_))) + | (Ap(_, _), Cast(d, Unknown(_), Sum(_) | Rec({item: Sum(_), _}))) => matches(dp, d) | (Ap(_, _), _) => DoesNotMatch @@ -285,7 +291,11 @@ and matches_cast_Sum = matches(dp, DHExp.apply_casts(d', side_casts)) | _ => DoesNotMatch } - | Cast(d', Sum(sm1) | Rec(_, Sum(sm1)), Sum(sm2) | Rec(_, Sum(sm2))) => + | Cast( + d', + Sum(sm1) | Rec({item: Sum(sm1), _}), + Sum(sm2) | Rec({item: Sum(sm2), _}), + ) => switch (cast_sum_maps(sm1, sm2)) { | Some(castmap) => matches_cast_Sum(ctr, dp, d', [castmap, ...castmaps]) | None => DoesNotMatch @@ -298,6 +308,7 @@ and matches_cast_Sum = | InvalidText(_) | Let(_) | Ap(_) + | TypAp(_) | ApBuiltin(_) | BinBoolOp(_) | BinIntOp(_) @@ -312,6 +323,7 @@ and matches_cast_Sum = | BoundVar(_) | FixF(_) | Fun(_) + | TypFun(_) | BoolLit(_) | IntLit(_) | FloatLit(_) @@ -389,7 +401,9 @@ and matches_cast_Tuple = | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch | Fun(_, _, _, _) => DoesNotMatch - | Closure(_, Fun(_)) => DoesNotMatch + | TypFun(_) => DoesNotMatch + | TypAp(_) => DoesNotMatch + | Closure(_, Fun(_) | TypFun(_)) => DoesNotMatch | Closure(_, _) => IndetMatch | Ap(_, _) => IndetMatch | ApBuiltin(_, _) => IndetMatch @@ -526,6 +540,8 @@ and matches_cast_Cons = | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch | Fun(_, _, _, _) => DoesNotMatch + | TypFun(_) => DoesNotMatch + | TypAp(_) => DoesNotMatch | Closure(_, d') => matches_cast_Cons(dp, d', elt_casts) | Ap(_, _) => IndetMatch | ApBuiltin(_, _) => IndetMatch @@ -672,6 +688,15 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = evaluate(env', d'); | Fun(_) => BoxedValue(Closure(env, d)) |> return + | TypFun(_) => BoxedValue(Closure(env, d)) |> return + + | TypAp(d1, _ty) => + let* r1 = evaluate(env, d1); + switch (r1) { + | BoxedValue(Closure(closure_env, TypFun(_, d3))) => + evaluate(closure_env, d3) + | _ => failwith("InvalidBoxedTypFun") + }; | Ap(d1, d2) => let* r1 = evaluate(env, d1); @@ -978,7 +1003,8 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = lambda closures are BoxedValues; other closures are all Indet. */ | Closure(_, d') => switch (d') { - | Fun(_) => BoxedValue(d) |> return + | Fun(_) + | TypFun(_) => BoxedValue(d) |> return | _ => Indet(d) |> return } @@ -1023,7 +1049,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = /* by canonical forms, d1' must be of the form d ?> */ switch (d1') { | Cast(d1'', ty'', Unknown(_)) => - if (Typ.eq(ty'', ty')) { + if (Typ.eq_syntactic(ty'', ty')) { BoxedValue(d1'') |> return; } else { Indet(FailedCast(d1', ty, ty')) |> return; @@ -1045,7 +1071,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = BoxedValue(Cast(d1', ty, ty')) |> return | (NotGroundOrHole(_), NotGroundOrHole(_)) => /* they might be eq in this case, so remove cast if so */ - if (Typ.eq(ty, ty')) { + if (Typ.eq_syntactic(ty, ty')) { result |> return; } else { BoxedValue(Cast(d1', ty, ty')) |> return; @@ -1063,7 +1089,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | (Hole, Ground) => switch (d1') { | Cast(d1'', ty'', Unknown(_)) => - if (Typ.eq(ty'', ty')) { + if (Typ.eq_syntactic(ty'', ty')) { Indet(d1'') |> return; } else { Indet(FailedCast(d1', ty, ty')) |> return; @@ -1085,7 +1111,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = Indet(Cast(d1', ty, ty')) |> return | (NotGroundOrHole(_), NotGroundOrHole(_)) => /* it might be eq in this case, so remove cast if so */ - if (Typ.eq(ty, ty')) { + if (Typ.eq_syntactic(ty, ty')) { result |> return; } else { Indet(Cast(d1', ty, ty')) |> return; diff --git a/src/haz3lcore/dynamics/EvaluatorPost.re b/src/haz3lcore/dynamics/EvaluatorPost.re index 18d4ea2b44..db405f5df1 100644 --- a/src/haz3lcore/dynamics/EvaluatorPost.re +++ b/src/haz3lcore/dynamics/EvaluatorPost.re @@ -70,6 +70,10 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => let* d2' = pp_eval(d2); Ap(d1', d2') |> return; + | TypAp(d1, ty) => + let* d1' = pp_eval(d1); + TypAp(d1', ty) |> return; + | ApBuiltin(f, args) => let* args' = args |> List.map(pp_eval) |> sequence; ApBuiltin(f, args') |> return; @@ -151,6 +155,7 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => | Let(_) | ConsistentCase(_) | Fun(_) + | TypFun(_) | EmptyHole(_) | NonEmptyHole(_) | ExpandingKeyword(_) @@ -176,6 +181,10 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => let* d = pp_uneval(env, d); Fun(dp, ty, d, s) |> return; + | TypFun(tpat, d1) => + let* d1' = pp_uneval(env, d1); + TypFun(tpat, d1') |> return; + | Let(dp, d1, d2) => /* d1 should already be evaluated, d2 is not */ let* d1 = pp_eval(d1); @@ -292,11 +301,19 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => let* d'' = pp_uneval(env, d'); Fun(dp, ty, d'', s) |> return; + | TypFun(tpat, d1) => + let* d1' = pp_uneval(env, d1); + TypFun(tpat, d1') |> return; + | Ap(d1, d2) => let* d1' = pp_uneval(env, d1); let* d2' = pp_uneval(env, d2); Ap(d1', d2') |> return; + | TypAp(d1, ty) => + let* d1' = pp_uneval(env, d1); + TypAp(d1', ty) |> return; + | ApBuiltin(f, args) => let* args' = args |> List.map(pp_uneval(env)) |> sequence; ApBuiltin(f, args') |> return; @@ -449,6 +466,8 @@ let rec track_children_of_hole = | BoundVar(_) => hii | FixF(_, _, d) | Fun(_, _, d, _) + | TypFun(_, d) + | TypAp(d, _) | Prj(d, _) | Cast(d, _, _) | FailedCast(d, _, _) diff --git a/src/haz3lcore/dynamics/Substitution.re b/src/haz3lcore/dynamics/Substitution.re index 92f8cff0fe..0b4ad84aa7 100644 --- a/src/haz3lcore/dynamics/Substitution.re +++ b/src/haz3lcore/dynamics/Substitution.re @@ -38,6 +38,7 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => let d3 = subst_var(d1, x, d3); Fun(dp, ty, d3, s); } + | TypFun(tpat, d3) => TypFun(tpat, subst_var(d1, x, d3)) | Closure(env, d3) => /* Closure shouldn't appear during substitution (which only is called from elaboration currently) */ @@ -48,6 +49,7 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => let d3 = subst_var(d1, x, d3); let d4 = subst_var(d1, x, d4); Ap(d3, d4); + | TypAp(d3, ty) => TypAp(subst_var(d1, x, d3), ty) | ApBuiltin(ident, args) => let args = List.map(subst_var(d1, x), args); ApBuiltin(ident, args); diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index f115522c3c..03b092232c 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -255,10 +255,15 @@ let forms: list((string, t)) = [ ("parens_pat", mk(ii, ["(", ")"], mk_op(Pat, [Pat]))), ("parens_typ", mk(ii, ["(", ")"], mk_op(Typ, [Typ]))), ("fun_", mk(ds, ["fun", "->"], mk_pre(P.fun_, Exp, [Pat]))), + ("typfun", mk(ds, ["typfun", "->"], mk_pre(P.fun_, Exp, [TPat]))), + ("forall", mk(ds, ["forall", "->"], mk_pre(P.fun_, Typ, [TPat]))), + ("rec", mk(ds, ["rec", "->"], mk_pre(P.fun_, Typ, [TPat]))), ("if_", mk(ds, ["if", "then", "else"], mk_pre(P.if_, Exp, [Exp, Exp]))), ("ap_exp", mk(ii, ["(", ")"], mk_post(P.ap, Exp, [Exp]))), ("ap_pat", mk(ii, ["(", ")"], mk_post(P.ap, Pat, [Pat]))), ("ap_typ", mk(ii, ["(", ")"], mk_post(P.ap, Typ, [Typ]))), + ("ap_exp_typ", mk(ii, ["@<", ">"], mk_post(P.ap, Exp, [Typ]))), + ("at_sign", mk_nul_infix("@", P.eqs)), // HACK: SUBSTRING REQ ("let_", mk(ds, ["let", "=", "in"], mk_pre(P.let_, Exp, [Pat, Exp]))), ( "type_alias", diff --git a/src/haz3lcore/statics/Kind.re b/src/haz3lcore/statics/Kind.re index 8db5638e94..cc3b0e6d34 100644 --- a/src/haz3lcore/statics/Kind.re +++ b/src/haz3lcore/statics/Kind.re @@ -1 +1,4 @@ -include TypBase.Kind; +[@deriving (show({with_path: false}), sexp, yojson)] +type t = + | Singleton(TypBase.t) + | Abstract; diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 1c170c63ee..35030a7b58 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -226,6 +226,7 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { | (["-"], []) => UnOp(Int(Minus), r) | (["!"], []) => UnOp(Bool(Not), r) | (["fun", "->"], [Pat(pat)]) => Fun(pat, r) + | (["typfun", "->"], [TPat(tpat)]) => TypFun(tpat, r) | (["let", "=", "in"], [Pat(pat), Exp(def)]) => Let(pat, def, r) | (["type", "=", "in"], [TPat(tpat), Typ(def)]) => TyAlias(tpat, def, r) @@ -241,9 +242,13 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { | ([(_id, t)], []) => switch (t) { | (["()"], []) => (l.term, l.ids) //TODO(andrew): new ap error - | (["(", ")"], [Exp(arg)]) => ret(Ap(l, arg)) - | _ => ret(hole(tm)) - } + ret( + switch (t) { + | (["(", ")"], [Exp(arg)]) => Ap(l, arg) + | (["@<", ">"], [Typ(ty)]) => TypAp(l, ty) + | _ => hole(tm) + }, + ) | _ => ret(hole(tm)) } | Bin(Exp(l), tiles, Exp(r)) as tm => @@ -400,6 +405,14 @@ and typ_term: unsorted => (UTyp.term, list(Id.t)) = { | Pre(tiles, Typ(t)) as tm => switch (tiles) { | ([(_, (["+"], []))], []) => ret(Sum([parse_sum_term(t)])) + | ([(_id, x)], []) => + ret( + switch (x) { + | (["forall", "->"], [TPat(tpat)]) => Forall(tpat, t) + | (["rec", "->"], [TPat(tpat)]) => Rec(tpat, t) + | _ => hole(tm) + }, + ) | _ => ret(hole(tm)) } | Bin(Typ(t1), tiles, Typ(t2)) as tm when is_typ_bsum(tiles) != None => diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 1fb4d040c5..32ccd26f48 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -236,6 +236,11 @@ and uexp_to_info_map = ~co_ctx=CoCtx.union([fn.co_ctx, arg.co_ctx]), m, ); + | TypAp(fn, utyp) => + let (fn, m_fn) = go(~mode=Typ.ap_mode, fn); + let Typ.{item: ty_body, _} = Typ.matched_forall(fn.ty); + let ty = Term.UTyp.to_typ(ctx, utyp); + add(~self=Just(Typ.subst(ty, ty_body)), ~free=fn.free, m_fn); | Fun(p, e) => let (mode_pat, mode_body) = Mode.of_arrow(ctx, mode); let (p, m) = go_pat(~is_synswitch=false, ~mode=mode_pat, p, m); @@ -245,6 +250,25 @@ and uexp_to_info_map = ~co_ctx=CoCtx.mk(ctx, p.ctx, e.co_ctx), m, ); + | TypFun({term: Var(name), _} as utpat, body) => + let mode_body = Typ.matched_forall_mode(mode); + let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + let ctx_body = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); + let (body, m_body) = go'(~ctx=ctx_body, ~mode=mode_body, body); + add( + ~self=Just(Forall({item: body.ty, name})), + ~free=body.free, + union_m([m_typat, m_body]), + ); + | TypFun(utpat, body) => + let mode_body = Typ.matched_forall_mode(mode); + let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + let (body, m_body) = go(~mode=mode_body, body); + add( + ~self=Just(Forall({item: body.ty, name: "expected_type_variable"})), + ~free=body.free, + union_m([m_typat, m_body]), + ); | Let(p, def, body) => let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); @@ -298,7 +322,7 @@ and uexp_to_info_map = /* Currently we disallow all type shadowing */ /* NOTE(andrew): Currently, UTyp.to_typ returns Unknown(TypeHole) for any type variable reference not in its ctx. So any free variables - in the definition won't be noticed. But we need to check for free + in the definition would be obliterated. But we need to check for free variables to decide whether to make a recursive type or not. So we tentatively add an abtract type to the ctx, representing the speculative rec parameter. */ @@ -314,6 +338,19 @@ and uexp_to_info_map = let ty = UTyp.to_typ(ctx, utyp); (ty, ctx, Ctx.extend_alias(ctx, name, UTPat.rep_id(typat), ty)); }; + /* NOTE(yuchen): Below is an alternative implementation that attempts to + add a rec whenever type alias is present. It may cause trouble to the + runtime, so precede with caution. */ + // Typ.lookup_surface(ty_pre) + // ? { + // let ty_rec = Typ.Rec({item: ty_pre, name}); + // let ctx_def = Ctx.add_alias(ctx, name, utpat_id(typat), ty_rec); + // (ty_rec, ctx_def, ctx_def); + // } + // : { + // let ty = Term.UTyp.to_typ(ctx, utyp); + // (ty, ctx, Ctx.add_alias(ctx, name, utpat_id(typat), ty)); + // }; }; let ctx_body = switch (Typ.get_sum_constructors(ctx, ty_def)) { @@ -334,6 +371,10 @@ and uexp_to_info_map = go'(~ctx, ~mode, body, m); let m = utyp_to_info_map(~ctx, ~ancestors, utyp, m) |> snd; add(~self=Just(ty_body), ~co_ctx, m); + | _ => + let (Info.{free, ty: ty_body, _}, m_body) = go'(~ctx, ~mode, body); + let m_typ = utyp_to_info_map(~ctx, ~ancestors, utyp) |> snd; + add(~self=Just(ty_body), ~free, union_m([m_typat, m_body, m_typ])); }; }; } @@ -472,7 +513,28 @@ and utyp_to_info_map = (m, []), variants, ); - add(m); + add(union_m(ms)); + | Forall({term: Var(_), _} as utpat, tbody) => + /* NOTE FROM ANDREW: probably want to add var to the body's ctx in this case? */ + let m = + utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; + let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + add(union_m([m, m_tpat])); // TODO: check with andrew + | Forall(utpat, tbody) => + let m = + utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; + let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + add(union_m([m, m_tpat])); // TODO: check with andrew + | Rec(utpat, tbody) => + /* NOTE FROM ANDREW: probably want to add var to the body's ctx in this case? */ + let m = + utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; + let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + add(union_m([m, m_tpat])); // TODO: check with andrew + | MultiHole(tms) => + let (_, ms) = + tms |> List.map(any_to_info_map(~ctx, ~ancestors)) |> List.split; + add(union_m(ms)); }; } and utpat_to_info_map = diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index f62a502e8c..c938b899d6 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -17,7 +17,6 @@ without correponding syntax classes */ include TermBase.Any; - type any = t; module UTyp = { [@deriving (show({with_path: false}), sexp, yojson)] @@ -36,7 +35,9 @@ module UTyp = { | Var | Constructor | Parens - | Ap; + | Ap + | Forall + | Rec; include TermBase.UTyp; @@ -67,7 +68,9 @@ module UTyp = { | Tuple(_) => Tuple | Parens(_) => Parens | Ap(_) => Ap - | Sum(_) => Sum; + | Sum(_) => Sum + | Forall(_) => Forall + | Rec(_) => Rec; let show_cls: cls => string = fun @@ -85,7 +88,9 @@ module UTyp = { | Tuple => "Product type" | Sum => "Sum type" | Parens => "Parenthesized type" - | Ap => "Constructor application"; + | Ap => "Constructor application" + | Forall => "Forall Type" + | Rec => "Recursive Type"; let rec is_arrow = (typ: t) => { switch (typ.term) { @@ -103,7 +108,30 @@ module UTyp = { | Var(_) | Constructor(_) | Ap(_) - | Sum(_) => false + | Sum(_) + | Forall(_) + | Rec(_) => false + }; + + let rec is_forall = (typ: t) => { + switch (typ.term) { + | Parens(typ) => is_forall(typ) + | Forall(_) => true + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Int + | Float + | Bool + | String + | Arrow(_) + | List(_) + | Tuple(_) + | Var(_) + | Constructor(_) + | Ap(_) + | Sum(_) + | Rec(_) => false }; }; @@ -128,6 +156,15 @@ module UTyp = { | Sum(uts) => Sum(to_ctr_map(ctx, uts)) | List(u) => List(to_typ(ctx, u)) | Parens(u) => to_typ(ctx, u) + | Forall({term: Var(name), _} as utpat, tbody) => + let ctx = Ctx.add_abstract(ctx, name, UTPat.rep_id(utpat)); + Forall({item: to_typ(ctx, tbody), name}); + | Forall(_, tbody) => to_typ(ctx, tbody) + // Forall is same as Rec + | Rec({term: Var(name), _} as utpat, tbody) => + let ctx = Ctx.add_abstract(ctx, name, UTPat.rep_id(utpat)); + Rec({item: to_typ(ctx, tbody), name}); + | Rec(_, tbody) => to_typ(ctx, tbody) /* The below cases should occur only inside sums */ | Constructor(_) | Ap(_) => Unknown(Internal) @@ -353,7 +390,7 @@ module UPat = { switch (pat.term) { | Parens(pat) => get_fun_var(pat) | TypeAnn(pat, typ) => - if (UTyp.is_arrow(typ)) { + if (UTyp.is_arrow(typ) || UTyp.is_forall(typ)) { get_var(pat) |> Option.map(var => var); } else { None; @@ -431,11 +468,13 @@ module UExp = { | ListLit | Constructor | Fun + | TypFun | Tuple | Var | Let | TyAlias | Ap + | TypAp | If | Seq | Test @@ -470,11 +509,13 @@ module UExp = { | ListLit(_) => ListLit | Constructor(_) => Constructor | Fun(_) => Fun + | TypFun(_) => TypFun | Tuple(_) => Tuple | Var(_) => Var | Let(_) => Let | TyAlias(_) => TyAlias | Ap(_) => Ap + | TypAp(_) => TypAp | If(_) => If | Seq(_) => Seq | Test(_) => Test @@ -548,7 +589,7 @@ module UExp = { | Invalid => "Invalid expression" | MultiHole => "Broken expression" | EmptyHole => "Empty expression hole" - | Triv => "Trivial litera" + | Triv => "Trivial literal" | Bool => "Boolean literal" | Int => "Integer literal" | Float => "Float literal" @@ -556,11 +597,13 @@ module UExp = { | ListLit => "List literal" | Constructor => "Constructor" | Fun => "Function literal" + | TypFun => "Type Function Literal" | Tuple => "Tuple literal" | Var => "Variable reference" | Let => "Let expression" | TyAlias => "Type Alias definition" | Ap => "Application" + | TypAp => "Type Application" | If => "If expression" | Seq => "Sequence expression" | Test => "Test" @@ -573,7 +616,8 @@ module UExp = { let rec is_fun = (e: t) => { switch (e.term) { - | Parens(e) => is_fun(e) + | Parens(e) + | TypFun(_, e) => is_fun(e) | Fun(_) => true | Invalid(_) | EmptyHole @@ -589,6 +633,7 @@ module UExp = { | Let(_) | TyAlias(_) | Ap(_) + | TypAp(_) | If(_) | Seq(_) | Test(_) @@ -617,10 +662,12 @@ module UExp = { | String(_) | ListLit(_) | Fun(_) + | TypFun(_) | Var(_) | Let(_) | TyAlias(_) | Ap(_) + | TypAp(_) | If(_) | Seq(_) | Test(_) diff --git a/src/haz3lcore/statics/TermBase.re b/src/haz3lcore/statics/TermBase.re index ee0280b17c..65d2ad7134 100644 --- a/src/haz3lcore/statics/TermBase.re +++ b/src/haz3lcore/statics/TermBase.re @@ -97,6 +97,35 @@ and UExp: { | Bool(op_bin_bool) | String(op_bin_string); + [@deriving (show({with_path: false}), sexp, yojson)] + type cls = + | Invalid + | EmptyHole + | MultiHole + | Triv + | Bool + | Int + | Float + | String + | ListLit + | Constructor + | Fun + | TypFun + | Tuple + | Var + | Let + | TyAlias + | Ap + | TypAp + | If + | Seq + | Test + | Parens + | Cons + | UnOp(op_un) + | BinOp(op_bin) + | Match; + [@deriving (show({with_path: false}), sexp, yojson)] type term = | Invalid(string) @@ -110,11 +139,13 @@ and UExp: { | ListLit(list(t)) | Constructor(string) | Fun(UPat.t, t) + | TypFun(UTPat.t, t) | Tuple(list(t)) | Var(Var.t) | Let(UPat.t, t, t) | TyAlias(UTPat.t, UTyp.t, t) | Ap(t, t) + | TypAp(t, UTyp.t) | If(t, t, t) | Seq(t, t) | Test(t) @@ -193,6 +224,35 @@ and UExp: { | Bool(op_bin_bool) | String(op_bin_string); + [@deriving (show({with_path: false}), sexp, yojson)] + type cls = + | Invalid + | EmptyHole + | MultiHole + | Triv + | Bool + | Int + | Float + | String + | ListLit + | Constructor + | Fun + | TypFun + | Tuple + | Var + | Let + | TyAlias + | Ap + | TypAp + | If + | Seq + | Test + | Parens + | Cons + | UnOp(op_un) + | BinOp(op_bin) + | Match; + [@deriving (show({with_path: false}), sexp, yojson)] type term = | Invalid(string) @@ -206,11 +266,13 @@ and UExp: { | ListLit(list(t)) | Constructor(string) | Fun(UPat.t, t) + | TypFun(UTPat.t, t) | Tuple(list(t)) | Var(Var.t) | Let(UPat.t, t, t) | TyAlias(UTPat.t, UTyp.t, t) | Ap(t, t) + | TypAp(t, UTyp.t) | If(t, t, t) | Seq(t, t) | Test(t) @@ -338,10 +400,16 @@ and UTyp: { | Tuple(list(t)) | Parens(t) | Ap(t, t) +<<<<<<< HEAD | Sum(list(variant)) and variant = | Variant(Constructor.t, list(Id.t), option(t)) | BadEntry(t) +======= + | USum(list(t)) + | Forall(UTPat.t, t) + | Rec(UTPat.t, t) +>>>>>>> 4c7587694 (merge in poly-adt) and t = { ids: list(Id.t), term, @@ -363,10 +431,16 @@ and UTyp: { | Tuple(list(t)) | Parens(t) | Ap(t, t) +<<<<<<< HEAD | Sum(list(variant)) and variant = | Variant(Constructor.t, list(Id.t), option(t)) | BadEntry(t) +======= + | USum(list(t)) + | Forall(UTPat.t, t) + | Rec(UTPat.t, t) +>>>>>>> 4c7587694 (merge in poly-adt) and t = { ids: list(Id.t), term, diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 3ad0570301..fcc763efd7 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -33,6 +33,7 @@ module rec Typ: { | Sum(sum_map) | Prod(list(t)) | Rec(TypVar.t, t) + | Forall(TypVar.t, t) and sum_map = ConstructorMap.t(option(t)); [@deriving (show({with_path: false}), sexp, yojson)] @@ -52,6 +53,7 @@ module rec Typ: { let join_type_provenance: (type_provenance, type_provenance) => type_provenance; let matched_arrow: t => (t, t); + let matched_forall: t => t; let matched_prod: (int, t) => list(t); let matched_cons: t => (t, t); let matched_list: t => t; @@ -91,6 +93,7 @@ module rec Typ: { | Sum(sum_map) | Prod(list(t)) | Rec(TypVar.t, t) + | Forall(TypVar.t, t) and sum_map = ConstructorMap.t(option(t)); [@deriving (show({with_path: false}), sexp, yojson)] @@ -128,6 +131,12 @@ module rec Typ: { | Unknown(SynSwitch) => (Unknown(SynSwitch), Unknown(SynSwitch)) | _ => (Unknown(Internal), Unknown(Internal)); + let matched_forall: t => (TypVar.t, t) = + fun + | Forall(t, ty) => (t, ty) + | Unknown(prov) => ("matched_forall", Unknown(prov)) + | _ => ("matched_forall", Unknown(Internal)); /* TODO: Might need to be fresh? */ + let matched_prod: (int, t) => list(t) = length => fun @@ -156,6 +165,7 @@ module rec Typ: { | Unknown(_) | Var(_) | Rec(_) + | Forall(_) | Sum(_) => precedence_Sum | List(_) => precedence_Const | Prod(_) => precedence_Prod @@ -174,6 +184,8 @@ module rec Typ: { | Sum(sm) => Sum(ConstructorMap.map(Option.map(subst(s, x)), sm)) | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) | Rec(y, ty) => Rec(y, subst(s, x, ty)) + | Forall(y, ty) when TypVar.eq(x, y) => Forall(y, ty) + | Forall(y, ty) => Forall(y, subst(s, x, ty)) | List(ty) => List(subst(s, x, ty)) | Var(y) => TypVar.eq(x, y) ? s : Var(y) }; @@ -191,6 +203,8 @@ module rec Typ: { switch (t1, t2) { | (Rec(x1, t1), Rec(x2, t2)) => eq(t1, subst(Var(x1), x2, t2)) | (Rec(_), _) => false + | (Forall(x1, t1), Forall(x2, t2)) => eq(t1, subst(Var(x1), x2, t2)) /* TODO: correct? */ + | (Forall(_), _) => false | (Int, Int) => true | (Int, _) => false | (Float, Float) => true @@ -234,6 +248,8 @@ module rec Typ: { ) | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) + | Forall({item: inside, name: n}) => [] /* free_vars(~bound=[x, ...bound], ty) */ + /* TODO: unclear how to finish this until Typ is fully rebased. */ }; /* Lattice join on types. This is a LUB join in the hazel2 @@ -281,7 +297,14 @@ module rec Typ: { let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); Rec(x1, ty_body); + | (Forall({item: t1, name}), Forall({item: t2, _})) => + /* See note above in Rec case */ + switch (join(Ctx.add_abstract(ctx, name, -1), t1, t2)) { + | Some(t) => Some(Forall({item: t, name})) + | None => None + } | (Rec(_), _) => None + | (Forall(_), _) => None | (Int, Int) => Some(Int) | (Int, _) => None | (Float, Float) => Some(Float) @@ -381,6 +404,8 @@ module rec Typ: { as in current implementation Recs do not occur in the surface syntax, so we won't try to jump to them. */ Rec(name, normalize(Ctx.extend_dummy_tvar(ctx, name), ty)) + | Forall(name, ty) => + Forall(name, normalize(Ctx.extend_dummy_tvar(ctx, name), ty)) }; }; @@ -413,6 +438,7 @@ module rec Typ: { | _ => false }; } + and Ctx: { [@deriving (show({with_path: false}), sexp, yojson)] type var_entry = { @@ -606,4 +632,35 @@ and Kind: { type t = | Singleton(Typ.t) | Abstract; + +/* Is not needed as not using debrujin indices */ +/* + let rec incr = (ty: t, i: int): t => { + switch (ty) { + | Var({item: Some(j), name}) => Var({item: Some(i + j), name}) + | Var(_) => ty + | List(ty) => List(incr(ty, i)) + | Arrow(ty1, ty2) => Arrow(incr(ty1, i), incr(ty2, i)) + | Sum(map) => + Sum( + VarMap.map( + ((_, ty)) => + switch (ty) { + | Some(ty) => Some(incr(ty, i)) + | None => None + }, + map, + ), + ) + | Prod(tys) => Prod(List.map(ty => incr(ty, i), tys)) + | Rec({item, name}) => Rec({item: incr(item, i), name}) + | Forall({item, name}) => Forall({item: incr(item, i), name}) + | Int => Int + | Float => Float + | Bool => Bool + | String => String + | Unknown(_) => ty + }; +*/ + }; diff --git a/src/haz3lcore/zipper/EditorUtil.re b/src/haz3lcore/zipper/EditorUtil.re index 4483997e1d..29bac63f20 100644 --- a/src/haz3lcore/zipper/EditorUtil.re +++ b/src/haz3lcore/zipper/EditorUtil.re @@ -66,9 +66,11 @@ let rec append_exp = (id, e1: TermBase.UExp.t, e2: TermBase.UExp.t) => { | ListLit(_) | Constructor(_) | Fun(_) + | TypFun(_) | Tuple(_) | Var(_) | Ap(_) + | TypAp(_) | If(_) | Test(_) | Parens(_) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 50bc3c36e7..e97934b72d 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -131,12 +131,21 @@ let common_ok_view = (cls: Term.Cls.t, ok: Info.ok_pat) => { let typ_ok_view = (cls: Term.Cls.t, ok: Info.ok_typ) => switch (ok) { | Type(_) when cls == Typ(EmptyHole) => [text("Fillable by any type")] - | Type(ty) => [Type.view(ty)] + | Type(ty) => [Type.view(ty), text("is a type")] | TypeAlias(name, ty_lookup) => [ Type.view(Var(name)), text("is an alias for"), Type.view(ty_lookup), ] + | Variant(name, sum_ty) => [ + Type.view(Var({name, item: None})), + text("is a sum type constuctor of type"), + Type.view(sum_ty), + ] + | VariantIncomplete(sum_ty) => [ + text("An incomplete sum type constuctor of type"), + Type.view(sum_ty), + ] | Variant(name, _sum_ty) => [Type.view(Var(name))] | VariantIncomplete(_sum_ty) => [text("is incomplete")] }; diff --git a/src/haz3lweb/view/LangDoc.re b/src/haz3lweb/view/LangDoc.re index b0eedb8869..f104290532 100644 --- a/src/haz3lweb/view/LangDoc.re +++ b/src/haz3lweb/view/LangDoc.re @@ -667,6 +667,20 @@ let get_doc = ), [], ); + | TypFun(_, _) => + // TODO (typfun) + let (doc, options) = + LangDocMessages.get_form_and_options( + LangDocMessages.triv_exp_group, + docs, + ); + get_message( + doc, + options, + LangDocMessages.triv_exp_group, + doc.explanation.message, + [], + ); | Fun(pat, body) => let basic = (doc: LangDocMessages.form, group_id, options) => { let pat_id = List.nth(pat.ids, 0); @@ -1902,6 +1916,20 @@ let get_doc = LangDocMessages.funapp_exp_coloring_ids, ); }; + | TypAp(_, _) => + // TODO (typfun) + let (doc, options) = + LangDocMessages.get_form_and_options( + LangDocMessages.triv_exp_group, + docs, + ); + get_message( + doc, + options, + LangDocMessages.triv_exp_group, + doc.explanation.message, + [], + ); | If(cond, then_, else_) => let (doc, options) = LangDocMessages.get_form_and_options( @@ -2795,6 +2823,9 @@ let get_doc = | Ap(_) => basic_info(LangDocMessages.sum_typ_unary_constructor_def_group) | Parens(_) => default // Shouldn't be hit? | Invalid(_) => default + // TODO (typfun): Add langdoc + | Forall(_) => default + | Rec(_) => default } | Some(InfoTPat(info)) => switch (info.term.term) { diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index ae88419f0e..290eb81f61 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -33,11 +33,16 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Float => ty_view("Float", "Float") | String => ty_view("String", "String") | Bool => ty_view("Bool", "Bool") - | Var(name) => ty_view("Var", name) - | Rec(x, t) => + | Var({name, _}) => ty_view("Var", name) + | Rec({item: t, name}) => div( ~attr=clss(["typ-view", "Rec"]), - [text("Rec " ++ x ++ ". "), view_ty(t)], + [text("Rec " ++ name ++ ". "), view_ty(t)], + ) + | Forall({item: t, name}) => + div( + ~attr=clss(["typ-view", "Forall"]), + [text("Forall " ++ name ++ ". "), view_ty(t)], ) | List(t) => div( diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 2dc53757b5..32780da431 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -60,6 +60,7 @@ let rec precedence = (~show_casts: bool, d: DHExp.t) => { | FailedCast(_) | InvalidOperation(_) | Fun(_) + | TypFun(_) | Closure(_) => DHDoc_common.precedence_const | Cast(d1, _, _) => show_casts ? DHDoc_common.precedence_const : precedence'(d1) @@ -71,7 +72,8 @@ let rec precedence = (~show_casts: bool, d: DHExp.t) => { | BinIntOp(op, _, _) => precedence_bin_int_op(op) | BinFloatOp(op, _, _) => precedence_bin_float_op(op) | BinStringOp(op, _, _) => precedence_bin_string_op(op) - | Ap(_) => DHDoc_common.precedence_Ap + | Ap(_) + | TypAp(_) => DHDoc_common.precedence_Ap | ApBuiltin(_) => DHDoc_common.precedence_Ap | Cons(_) => DHDoc_common.precedence_Cons | ListConcat(_) => DHDoc_common.precedence_Plus @@ -193,6 +195,11 @@ let rec mk = go'(~parenthesize=false, d2), ); DHDoc_common.mk_Ap(mk_cast(doc1), mk_cast(doc2)); + | TypAp(d1, ty) => + DHDoc_common.mk_Ap( + mk_cast(go(~enforce_inline, d1)), + DHDoc_Typ.mk(~enforce_inline=true, ty), + ) | ApBuiltin(ident, args) => switch (args) { | [hd, ...tl] => @@ -262,7 +269,8 @@ let rec mk = ]), mk_cast(go(~enforce_inline=false, dbody)), ]); - | FailedCast(Cast(d, ty1, ty2), ty2', ty3) when Typ.eq(ty2, ty2') => + | FailedCast(Cast(d, ty1, ty2), ty2', ty3) + when Typ.eq_syntactic(ty2, ty2') => let (d_doc, _) = go'(d); let cast_decoration = hcats([ @@ -338,6 +346,8 @@ let rec mk = | Some(name) => annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")) }; } + | TypFun(_tpat, _dbody) => + annot(DHAnnot.Collapsed, text("")) | FixF(x, ty, dbody) => if (settings.show_fn_bodies) { let doc_body = (~enforce_inline) => diff --git a/src/haz3lweb/view/dhcode/layout/HTypDoc.re b/src/haz3lweb/view/dhcode/layout/HTypDoc.re index 8acbc0455f..bff18b7240 100644 --- a/src/haz3lweb/view/dhcode/layout/HTypDoc.re +++ b/src/haz3lweb/view/dhcode/layout/HTypDoc.re @@ -50,7 +50,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { | Float => (text("Float"), parenthesize) | Bool => (text("Bool"), parenthesize) | String => (text("String"), parenthesize) - | Var(name) => (text(name), parenthesize) + | Var({name, _}) => (text(name), parenthesize) | List(ty) => ( hcats([ mk_delim("["), @@ -106,9 +106,21 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { ) |> hcats; (center, true); - | Rec(x, ty) => ( + | Rec({item: ty, name}) => ( hcats([ - text("Rec " ++ x ++ ".{"), + text("Rec " ++ name ++ ".{"), + ( + (~enforce_inline) => + annot(HTypAnnot.Step(0), mk(~enforce_inline, ty)) + ) + |> pad_child(~enforce_inline), + mk_delim("}"), + ]), + parenthesize, + ) + | Forall({item: ty, name}) => ( + hcats([ + text("Forall " ++ name ++ ".{"), ( (~enforce_inline) => annot(HTypAnnot.Step(0), mk(~enforce_inline, ty)) From 7e495cb10aee70d400cb649b33199e34d7512f5a Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Mon, 20 Feb 2023 10:50:49 -0500 Subject: [PATCH 022/229] Fixed body_ctx of Forall and Rec in Statics --- src/haz3lcore/statics/Statics.re | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 32ccd26f48..4066b837ba 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -514,10 +514,16 @@ and utyp_to_info_map = variants, ); add(union_m(ms)); - | Forall({term: Var(_), _} as utpat, tbody) => - /* NOTE FROM ANDREW: probably want to add var to the body's ctx in this case? */ + | Forall({term: Var(name), _} as utpat, tbody) => + let body_ctx = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); let m = - utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; + utyp_to_info_map( + tbody, + ~ctx=body_ctx, + ~ancestors, + ~expects=TypeExpected, + ) + |> snd; let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; add(union_m([m, m_tpat])); // TODO: check with andrew | Forall(utpat, tbody) => @@ -525,8 +531,19 @@ and utyp_to_info_map = utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; add(union_m([m, m_tpat])); // TODO: check with andrew + | Rec({term: Var(name), _} as utpat, tbody) => + let body_ctx = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); + let m = + utyp_to_info_map( + tbody, + ~ctx=body_ctx, + ~ancestors, + ~expects=TypeExpected, + ) + |> snd; + let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; + add(union_m([m, m_tpat])); // TODO: check with andrew | Rec(utpat, tbody) => - /* NOTE FROM ANDREW: probably want to add var to the body's ctx in this case? */ let m = utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; From bc7e4717446dd60b97ffd7f17d98dc9630647fb1 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Mon, 20 Feb 2023 11:40:43 -0500 Subject: [PATCH 023/229] Allow Indet on the left of TypAp in Evaluator, similar to Ap --- src/haz3lcore/dynamics/Evaluator.re | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 17568ca412..4b5445eaa8 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -695,7 +695,8 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = switch (r1) { | BoxedValue(Closure(closure_env, TypFun(_, d3))) => evaluate(closure_env, d3) - | _ => failwith("InvalidBoxedTypFun") + | Indet(_) => r1 |> return + | _ => failwith("InvalidBoxedTypFun: " ++ show(r1)) }; | Ap(d1, d2) => From ceee07c7ad3c11d36b06a3ba9882f15d42ee7ca5 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Mon, 20 Feb 2023 11:55:57 -0500 Subject: [PATCH 024/229] Fix mode of TypAp to Syn, not SynFun --- src/haz3lcore/statics/Statics.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 4066b837ba..feff396a1b 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -237,7 +237,7 @@ and uexp_to_info_map = m, ); | TypAp(fn, utyp) => - let (fn, m_fn) = go(~mode=Typ.ap_mode, fn); + let (fn, m_fn) = go(~mode=Syn, fn); let Typ.{item: ty_body, _} = Typ.matched_forall(fn.ty); let ty = Term.UTyp.to_typ(ctx, utyp); add(~self=Just(Typ.subst(ty, ty_body)), ~free=fn.free, m_fn); From 8770d6e8f34612a66cc2c2c671a226e181c85c14 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Mon, 20 Feb 2023 12:13:29 -0500 Subject: [PATCH 025/229] Update is_fun and is_fun_var to recognize forall --- src/haz3lcore/statics/Term.re | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index c938b899d6..96d6ed573c 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -321,7 +321,8 @@ module UPat = { let rec is_fun_var = (pat: t) => { switch (pat.term) { | Parens(pat) => is_fun_var(pat) - | TypeAnn(pat, typ) => is_var(pat) && UTyp.is_arrow(typ) + | TypeAnn(pat, typ) => + is_var(pat) && (UTyp.is_arrow(typ) || UTyp.is_forall(typ)) | Invalid(_) | EmptyHole | MultiHole(_) @@ -614,10 +615,13 @@ module UExp = { | UnOp(op) => show_unop(op) | Match => "Case expression"; + // TODO (poly): May need to create a separate is_typfun function, + // so that is_fun pairs with is_fun_var over Arrow + // and is_typfun pairs with is_typfun_var over Forall let rec is_fun = (e: t) => { switch (e.term) { - | Parens(e) - | TypFun(_, e) => is_fun(e) + | Parens(e) => is_fun(e) + | TypFun(_) | Fun(_) => true | Invalid(_) | EmptyHole From 031067efd96ae2205fed52b50678375f98b97fe2 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 1 May 2023 00:47:16 -0400 Subject: [PATCH 026/229] Implement semantics of type function application as type substition on terms. --- src/haz3lcore/dynamics/Evaluator.re | 71 ++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 4b5445eaa8..9744ce0f69 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -636,6 +636,74 @@ let eval_bin_string_op = | Equals => BoolLit(s1 == s2) }; +let rec ty_subst = + (~idx=0, exp, targ) + : DHExp.t /* TODO: Maybe just keep error instead of recursing? */ => { + open DH.DHExp; + let re = e2 => ty_subst(~idx, e2, targ); + switch (exp) { + | Cast(t, t1, t2) => + Cast(re(t), Typ.subst(targ, ~x=idx, t1), Typ.subst(targ, ~x=idx, t2)) + | FixF(arg, ty, body) => FixF(arg, Typ.subst(targ, ~x=idx, ty), re(body)) + | Fun(arg, ty, body, var) => + Fun(arg, Typ.subst(targ, ~x=idx, ty), re(body), var) + | TypAp(tfun, ty) => TypAp(re(tfun), Typ.subst(targ, ~x=idx, ty)) + | ListLit(mv, mvi, lerr, t, lst) => + ListLit(mv, mvi, lerr, Typ.subst(targ, ~x=idx, t), List.map(re, lst)) + + | TypFun(utpat, body) => TypFun(utpat, ty_subst(~idx=idx + 1, body, targ)) + + | NonEmptyHole(errstat, mv, hid, t) => + NonEmptyHole(errstat, mv, hid, re(t)) + | InconsistentBranches(mv, hid, case) => + InconsistentBranches(mv, hid, ty_subst_case(~idx, case, targ)) + | Closure(ce, t) => Closure(ce, re(t)) + | Sequence(t1, t2) => Sequence(re(t1), re(t2)) + | Let(dhpat, t1, t2) => Let(dhpat, re(t1), re(t2)) + | Ap(t1, t2) => Ap(re(t1), re(t2)) + | ApBuiltin(s, args) => ApBuiltin(s, List.map(re, args)) + | BinBoolOp(op, t1, t2) => BinBoolOp(op, re(t1), re(t2)) + | BinIntOp(op, t1, t2) => BinIntOp(op, re(t1), re(t2)) + | BinFloatOp(op, t1, t2) => BinFloatOp(op, re(t1), re(t2)) + | BinStringOp(op, t1, t2) => BinStringOp(op, re(t1), re(t2)) + | Cons(t1, t2) => Cons(re(t1), re(t2)) + | Tuple(args) => Tuple(List.map(re, args)) + | Prj(t, n) => Prj(re(t), n) + | ConsistentCase(case) => ConsistentCase(ty_subst_case(~idx, case, targ)) + | InvalidOperation(t, err) => InvalidOperation(re(t), err) + + | EmptyHole(_) + | ExpandingKeyword(_, _, _) + | FreeVar(_, _, _) + | InvalidText(_, _, _) + | BoundVar(_) + | TestLit(_) + | BoolLit(_) + | IntLit(_) + | FloatLit(_) + | StringLit(_) + | Tag(_) + | FailedCast(_, _, _) => exp + }; +} //TODO: is this correct? +//TODO: Need to check again for inconsistency? +//TODO: Same as inconsistent branch. +/* cases with types we may need to substitute */ +/* special case of changing debruijn indices */ +/* cases where we just syntactically recurse */ +/* Recursion is probably necessary in the following cases for error reporting */ +/* Cases where we don't need to recurse */ + +and ty_subst_case = (~idx=0, Case(t, rules, n), targ) => + Case( + ty_subst(~idx, t, targ), + List.map( + (DHExp.Rule(dhpat, t)) => DHExp.Rule(dhpat, ty_subst(~idx, t, targ)), + rules, + ), + n, + ); + let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = (env, d) => { /* Increment number of evaluation steps (calls to `evaluate`). */ @@ -691,10 +759,11 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | TypFun(_) => BoxedValue(Closure(env, d)) |> return | TypAp(d1, _ty) => + // print_endline("Evaluating TypAp."); let* r1 = evaluate(env, d1); switch (r1) { | BoxedValue(Closure(closure_env, TypFun(_, d3))) => - evaluate(closure_env, d3) + evaluate(closure_env, ty_subst(d3, _ty)) | Indet(_) => r1 |> return | _ => failwith("InvalidBoxedTypFun: " ++ show(r1)) }; From d210f8f5542148122ee037829a062de74b5ac043 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 23 May 2023 03:51:48 -0400 Subject: [PATCH 027/229] Add synthesis mode for type function and add necessary casting cases. Add ground case for forall type (as Forall _ . ?). --- src/haz3lcore/dynamics/Elaborator.re | 13 +++++++++++++ src/haz3lcore/dynamics/Evaluator.re | 10 ++-------- src/haz3lcore/statics/Info.re | 15 +++++++++++++-- src/haz3lcore/statics/Mode.re | 20 ++++++++++++++------ src/haz3lcore/statics/Statics.re | 7 ++++++- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index ef76735da6..46eca8d3c0 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -37,6 +37,18 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | Arrow(_) => d | _ => failwith("Elaborator.wrap: SynFun non-arrow-type") } + | SynTypFun => + switch (self_ty) { + | Unknown(prov) => + /* ? |> forall _. ? */ + DHExp.cast( + d, + Unknown(prov), + Forall({item: Unknown(prov), name: "_"}), + ) + | Forall(_) => d + | _ => failwith("Elaborator.wrap: SynTypFun non-forall-type") + } | Ana(ana_ty) => let ana_ty = Typ.normalize(ctx, ana_ty); /* Forms with special ana rules get cast from their appropriate Matched types */ @@ -71,6 +83,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | _ => d } | Ap(Constructor(_), _) + | TypAp(Constructor(_), _) | Constructor(_) => switch (ana_ty, self_ty) { | (Unknown(prov), Rec({item: Sum(_), _})) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 9744ce0f69..c49369ef6f 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -51,6 +51,7 @@ let rec ground_cases_of = (ty: Typ.t): ground_cases => { | Var(_) | Rec(_) | Arrow(Unknown(_), Unknown(_)) + | Forall({item: Unknown(_), name: _}) | List(Unknown(_)) => Ground | Prod(tys) => if (List.for_all( @@ -686,13 +687,7 @@ let rec ty_subst = | FailedCast(_, _, _) => exp }; } //TODO: is this correct? -//TODO: Need to check again for inconsistency? -//TODO: Same as inconsistent branch. -/* cases with types we may need to substitute */ -/* special case of changing debruijn indices */ -/* cases where we just syntactically recurse */ -/* Recursion is probably necessary in the following cases for error reporting */ -/* Cases where we don't need to recurse */ +//TODO: Inconsistent cases: need to check again for inconsistency? and ty_subst_case = (~idx=0, Case(t, rules, n), targ) => Case( @@ -759,7 +754,6 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | TypFun(_) => BoxedValue(Closure(env, d)) |> return | TypAp(d1, _ty) => - // print_endline("Evaluating TypAp."); let* r1 = evaluate(env, d1); switch (r1) { | BoxedValue(Closure(closure_env, TypFun(_, d3))) => diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 69d3871db6..f860def7f8 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -259,7 +259,18 @@ let pat_ty: pat => Typ.t = ({ty, _}) => ty; let rec status_common = (ctx: Ctx.t, mode: Mode.t, self: Self.t): status_common => switch (self, mode) { - | (Just(syn), Syn) => NotInHole(Syn(syn)) + | (Just(ty), Syn) => NotInHole(Syn(ty)) + | (Just(ty), SynFun) => + switch (Typ.join(ctx, Arrow(Unknown(Internal), Unknown(Internal)), ty)) { + | Some(_) => NotInHole(Syn(ty)) + | None => InHole(InconsistentWithArrow(ty)) + } + | (Just(ty), SynTypFun) => + /* Use ty first to preserve name if it exists. */ + switch (Typ.join(ctx, ty, Forall({item: Unknown(Internal), name: "_"}))) { + | Some(_) => NotInHole(Syn(ty)) + | None => InHole(InconsistentWithArrow(ty)) + } | (Just(syn), Ana(ana)) => switch (Typ.join_fix(ctx, ana, syn)) { | None => InHole(Inconsistent(Expectation({syn, ana}))) @@ -293,7 +304,7 @@ let rec status_common = Ana(InternallyInconsistent({ana, nojoin: Typ.of_source(tys)})), ) }; - | (NoJoin(_, tys), Syn | SynFun) => + | (NoJoin(_, tys), Syn | SynFun | SynTypFun) => InHole(Inconsistent(Internal(Typ.of_source(tys)))) }; diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index 58594f928d..9af16e32c4 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -20,6 +20,7 @@ open OptUtil.Syntax; [@deriving (show({with_path: false}), sexp, yojson)] type t = | SynFun /* Used only in function position of applications */ + | SynTypFun | Syn | Ana(Typ.t); @@ -31,11 +32,13 @@ let ty_of: t => Typ.t = | Ana(ty) => ty | Syn => Unknown(SynSwitch) | SynFun => Arrow(Unknown(SynSwitch), Unknown(SynSwitch)); + | SynTypFun => Forall("syntypfun", Unknown(SynSwitch)) /* TODO: naming the type variable? */ let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => switch (mode) { | Syn - | SynFun => (Syn, Syn) + | SynFun + | SynTypFun => (Syn, Syn) | Ana(ty) => ty |> Typ.weak_head_normalize(ctx) @@ -46,7 +49,8 @@ let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => let of_prod = (ctx: Ctx.t, mode: t, length): list(t) => switch (mode) { | Syn - | SynFun => List.init(length, _ => Syn) + | SynFun + | SynTypFun => List.init(length, _ => Syn) | Ana(ty) => ty |> Typ.weak_head_normalize(ctx) @@ -60,28 +64,32 @@ let matched_list_normalize = (ctx: Ctx.t, ty: Typ.t): Typ.t => let of_cons_hd = (ctx: Ctx.t, mode: t): t => switch (mode) { | Syn - | SynFun => Syn + | SynFun + | SynTypFun => Syn | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) }; let of_cons_tl = (ctx: Ctx.t, mode: t, hd_ty: Typ.t): t => switch (mode) { | Syn - | SynFun => Ana(List(hd_ty)) + | SynFun + | SynTypFun => Ana(List(hd_ty)) | Ana(ty) => Ana(List(matched_list_normalize(ctx, ty))) }; let of_list = (ctx: Ctx.t, mode: t): t => switch (mode) { | Syn - | SynFun => Syn + | SynFun + | SynTypFun => Syn | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) }; let of_list_concat = (mode: t): t => switch (mode) { | Syn - | SynFun => Ana(List(Unknown(SynSwitch))) + | SynFun + | SynTypFun => Ana(List(Unknown(SynSwitch))) | Ana(ty) => Ana(List(Typ.matched_list(ty))) }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index feff396a1b..64d5944947 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -237,7 +237,12 @@ and uexp_to_info_map = m, ); | TypAp(fn, utyp) => - let (fn, m_fn) = go(~mode=Syn, fn); + /* Might need something similar to Ap's case where we check analysis mode when tagged? */ + let typfn_mode = /* switch(fn) { + | {term: Tag(name), _} => Typ.tag_typap_mode(ctx, mode, name) + | _ => Typ.typap_mode + }; */ Typ.typap_mode; + let (fn, m_fn) = go(~mode=typfn_mode, fn); let Typ.{item: ty_body, _} = Typ.matched_forall(fn.ty); let ty = Term.UTyp.to_typ(ctx, utyp); add(~self=Just(Typ.subst(ty, ty_body)), ~free=fn.free, m_fn); From 4d02ccbec40fb108e76eabff330b6cf5e527eb9d Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 23 May 2023 05:57:41 -0400 Subject: [PATCH 028/229] Add rule for evaluation of type application on cast. --- src/haz3lcore/dynamics/Evaluator.re | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index c49369ef6f..24eaeaa8f8 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -753,11 +753,30 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | Fun(_) => BoxedValue(Closure(env, d)) |> return | TypFun(_) => BoxedValue(Closure(env, d)) |> return - | TypAp(d1, _ty) => + | TypAp(d1, tau) => let* r1 = evaluate(env, d1); switch (r1) { - | BoxedValue(Closure(closure_env, TypFun(_, d3))) => - evaluate(closure_env, ty_subst(d3, _ty)) + | BoxedValue(Closure(closure_env, TypFun(_, d2))) => + // TODO: Maybe additional cases to be done? + evaluate(closure_env, ty_subst(d2, tau)) + | BoxedValue( + Cast( + d1', + Forall({item: t, name: _}), + Forall({item: t', name: _}), + ), + ) + | Indet( + Cast( + d1', + Forall({item: t, name: _}), + Forall({item: t', name: _}), + ), + ) => + evaluate( + env, + Cast(TypAp(d1', tau), Typ.subst(t, tau), Typ.subst(t', tau)), + ) | Indet(_) => r1 |> return | _ => failwith("InvalidBoxedTypFun: " ++ show(r1)) }; From b52560c8b8540d15c2bb2210074c8431e9902141 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 24 Aug 2023 20:26:07 -0400 Subject: [PATCH 029/229] Some resolutions to conflicts from rebasing. --- src/haz3lcore/dynamics/DH.re | 2 +- src/haz3lcore/statics/Info.re | 19 +++---- src/haz3lcore/statics/Kind.re | 2 +- src/haz3lcore/statics/MakeTerm.re | 12 ++-- src/haz3lcore/statics/Mode.re | 28 +++++++--- src/haz3lcore/statics/Statics.re | 16 ++---- src/haz3lcore/statics/Term.re | 92 +++++++++++++++++-------------- src/haz3lcore/statics/TermBase.re | 16 ++---- src/haz3lcore/statics/TypBase.re | 74 ++++++++++++------------- 9 files changed, 130 insertions(+), 131 deletions(-) diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index 72f08d00a6..931d27d758 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -145,7 +145,7 @@ module rec DHExp: { | xs => Tuple(xs); let cast = (d: t, t1: Typ.t, t2: Typ.t): t => - if (Typ.eq_syntactic(t1, t2) || t2 == Unknown(SynSwitch)) { + if (Typ.eq(t1, t2) || t2 == Unknown(SynSwitch)) { d; } else { Cast(d, t1, t2); diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index f860def7f8..af8aa33b15 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -261,28 +261,23 @@ let rec status_common = switch (self, mode) { | (Just(ty), Syn) => NotInHole(Syn(ty)) | (Just(ty), SynFun) => - switch (Typ.join(ctx, Arrow(Unknown(Internal), Unknown(Internal)), ty)) { + switch ( + Typ.join_fix(ctx, Arrow(Unknown(Internal), Unknown(Internal)), ty) + ) { | Some(_) => NotInHole(Syn(ty)) - | None => InHole(InconsistentWithArrow(ty)) + | None => InHole(Inconsistent(WithArrow(ty))) } | (Just(ty), SynTypFun) => /* Use ty first to preserve name if it exists. */ - switch (Typ.join(ctx, ty, Forall({item: Unknown(Internal), name: "_"}))) { + switch (Typ.join_fix(ctx, ty, Forall("_", Unknown(Internal)))) { | Some(_) => NotInHole(Syn(ty)) - | None => InHole(InconsistentWithArrow(ty)) + | None => InHole(Inconsistent(WithArrow(ty))) } | (Just(syn), Ana(ana)) => switch (Typ.join_fix(ctx, ana, syn)) { | None => InHole(Inconsistent(Expectation({syn, ana}))) | Some(join) => NotInHole(Ana(Consistent({ana, syn, join}))) } - | (Just(syn), SynFun) => - switch ( - Typ.join_fix(ctx, Arrow(Unknown(Internal), Unknown(Internal)), syn) - ) { - | None => InHole(Inconsistent(WithArrow(syn))) - | Some(_) => NotInHole(Syn(syn)) - } | (IsConstructor({name, syn_ty}), _) => /* If a ctr is being analyzed against (an arrow type returning) a sum type having that ctr as a variant, its self type is @@ -310,7 +305,7 @@ let rec status_common = let status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => switch (mode, self) { - | (Syn | Ana(_), Common(self_pat)) + | (Syn | SynTypFun | Ana(_), Common(self_pat)) | (SynFun, Common(IsConstructor(_) as self_pat)) => /* Little bit of a hack. Anything other than a bound ctr will, in function position, have SynFun mode (see Typ.ap_mode). Since we diff --git a/src/haz3lcore/statics/Kind.re b/src/haz3lcore/statics/Kind.re index cc3b0e6d34..21b1604440 100644 --- a/src/haz3lcore/statics/Kind.re +++ b/src/haz3lcore/statics/Kind.re @@ -1,4 +1,4 @@ [@deriving (show({with_path: false}), sexp, yojson)] type t = - | Singleton(TypBase.t) + | Singleton(Typ.t) | Abstract; diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 35030a7b58..68d4c88cc3 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -242,13 +242,10 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { | ([(_id, t)], []) => switch (t) { | (["()"], []) => (l.term, l.ids) //TODO(andrew): new ap error - ret( - switch (t) { - | (["(", ")"], [Exp(arg)]) => Ap(l, arg) - | (["@<", ">"], [Typ(ty)]) => TypAp(l, ty) - | _ => hole(tm) - }, - ) + | (["(", ")"], [Exp(arg)]) => ret(Ap(l, arg)) + | (["@<", ">"], [Typ(ty)]) => ret(TypAp(l, ty)) + | _ => ret(hole(tm)) + } | _ => ret(hole(tm)) } | Bin(Exp(l), tiles, Exp(r)) as tm => @@ -296,7 +293,6 @@ and exp_term: unsorted => (UExp.term, list(Id.t)) = { } | tm => ret(hole(tm)); } - and pat = unsorted => { let (term, inner_ids) = pat_term(unsorted); let ids = ids(unsorted) @ inner_ids; diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index 9af16e32c4..267f465abb 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -31,13 +31,13 @@ let ty_of: t => Typ.t = fun | Ana(ty) => ty | Syn => Unknown(SynSwitch) - | SynFun => Arrow(Unknown(SynSwitch), Unknown(SynSwitch)); - | SynTypFun => Forall("syntypfun", Unknown(SynSwitch)) /* TODO: naming the type variable? */ + | SynFun => Arrow(Unknown(SynSwitch), Unknown(SynSwitch)) + | SynTypFun => Forall("syntypfun", Unknown(SynSwitch)); /* TODO: naming the type variable? */ let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => (Syn, Syn) | Ana(ty) => ty @@ -46,10 +46,20 @@ let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => |> TupleUtil.map2(ana) }; +let of_forall = (mode: t): t => + switch (mode) { + | Syn + | SynFun + | SynTypFun => Syn + | Ana(ty) => + let (_, item) = Typ.matched_forall(ty); + Ana(item); + }; + let of_prod = (ctx: Ctx.t, mode: t, length): list(t) => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => List.init(length, _ => Syn) | Ana(ty) => ty @@ -64,7 +74,7 @@ let matched_list_normalize = (ctx: Ctx.t, ty: Typ.t): Typ.t => let of_cons_hd = (ctx: Ctx.t, mode: t): t => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => Syn | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) }; @@ -72,7 +82,7 @@ let of_cons_hd = (ctx: Ctx.t, mode: t): t => let of_cons_tl = (ctx: Ctx.t, mode: t, hd_ty: Typ.t): t => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => Ana(List(hd_ty)) | Ana(ty) => Ana(List(matched_list_normalize(ctx, ty))) }; @@ -80,7 +90,7 @@ let of_cons_tl = (ctx: Ctx.t, mode: t, hd_ty: Typ.t): t => let of_list = (ctx: Ctx.t, mode: t): t => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => Syn | Ana(ty) => Ana(matched_list_normalize(ctx, ty)) }; @@ -88,7 +98,7 @@ let of_list = (ctx: Ctx.t, mode: t): t => let of_list_concat = (mode: t): t => switch (mode) { | Syn - | SynFun + | SynFun | SynTypFun => Ana(List(Unknown(SynSwitch))) | Ana(ty) => Ana(List(Typ.matched_list(ty))) }; @@ -139,3 +149,5 @@ let of_ap = (ctx, mode, ctr: option(Constructor.t)): t => } | None => SynFun }; + +let typap_mode: t = SynTypFun; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 64d5944947..caa8545166 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -237,15 +237,11 @@ and uexp_to_info_map = m, ); | TypAp(fn, utyp) => - /* Might need something similar to Ap's case where we check analysis mode when tagged? */ - let typfn_mode = /* switch(fn) { - | {term: Tag(name), _} => Typ.tag_typap_mode(ctx, mode, name) - | _ => Typ.typap_mode - }; */ Typ.typap_mode; - let (fn, m_fn) = go(~mode=typfn_mode, fn); - let Typ.{item: ty_body, _} = Typ.matched_forall(fn.ty); + let typfn_mode = Mode.typap_mode; + let (fn, m_fn) = go(~mode=typfn_mode, fn, m); + let (name, ty_body) = Typ.matched_forall(fn.ty); let ty = Term.UTyp.to_typ(ctx, utyp); - add(~self=Just(Typ.subst(ty, ty_body)), ~free=fn.free, m_fn); + add(~self=Just(Typ.subst(ty, name, ty_body)), ~co_ctx=fn.co_ctx, m_fn); | Fun(p, e) => let (mode_pat, mode_body) = Mode.of_arrow(ctx, mode); let (p, m) = go_pat(~is_synswitch=false, ~mode=mode_pat, p, m); @@ -256,7 +252,7 @@ and uexp_to_info_map = m, ); | TypFun({term: Var(name), _} as utpat, body) => - let mode_body = Typ.matched_forall_mode(mode); + let mode_body = Mode.of_forall(mode); let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; let ctx_body = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); let (body, m_body) = go'(~ctx=ctx_body, ~mode=mode_body, body); @@ -266,7 +262,7 @@ and uexp_to_info_map = union_m([m_typat, m_body]), ); | TypFun(utpat, body) => - let mode_body = Typ.matched_forall_mode(mode); + let mode_body = Mode.of_forall(mode); let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; let (body, m_body) = go(~mode=mode_body, body); add( diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 96d6ed573c..b075c17c4c 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -18,6 +18,43 @@ include TermBase.Any; type any = t; + +module UTPat = { + [@deriving (show({with_path: false}), sexp, yojson)] + type cls = + | Invalid + | EmptyHole + | MultiHole + | Var; + + include TermBase.UTPat; + + let rep_id = ({ids, _}) => { + assert(ids != []); + List.hd(ids); + }; + + let hole = (tms: list(any)) => + switch (tms) { + | [] => EmptyHole + | [_, ..._] => MultiHole(tms) + }; + + let cls_of_term: term => cls = + fun + | Invalid(_) => Invalid + | EmptyHole => EmptyHole + | MultiHole(_) => MultiHole + | Var(_) => Var; + + let show_cls: cls => string = + fun + | Invalid => "Invalid type alias" + | MultiHole => "Broken type alias" + | EmptyHole => "Empty type alias hole" + | Var => "Type alias"; +}; + module UTyp = { [@deriving (show({with_path: false}), sexp, yojson)] type cls = @@ -112,7 +149,8 @@ module UTyp = { | Forall(_) | Rec(_) => false }; - + }; + let rec is_forall = (typ: t) => { switch (typ.term) { | Parens(typ) => is_forall(typ) @@ -157,13 +195,21 @@ module UTyp = { | List(u) => List(to_typ(ctx, u)) | Parens(u) => to_typ(ctx, u) | Forall({term: Var(name), _} as utpat, tbody) => - let ctx = Ctx.add_abstract(ctx, name, UTPat.rep_id(utpat)); - Forall({item: to_typ(ctx, tbody), name}); + let ctx = + Ctx.extend_tvar( + ctx, + {name, id: UTPat.rep_id(utpat), kind: Abstract}, + ); + Forall(name, to_typ(ctx, tbody)); | Forall(_, tbody) => to_typ(ctx, tbody) // Forall is same as Rec | Rec({term: Var(name), _} as utpat, tbody) => - let ctx = Ctx.add_abstract(ctx, name, UTPat.rep_id(utpat)); - Rec({item: to_typ(ctx, tbody), name}); + let ctx = + Ctx.extend_tvar( + ctx, + {name, id: UTPat.rep_id(utpat), kind: Abstract}, + ); + Rec(name, to_typ(ctx, tbody)); | Rec(_, tbody) => to_typ(ctx, tbody) /* The below cases should occur only inside sums */ | Constructor(_) @@ -186,42 +232,6 @@ module UTyp = { }; }; -module UTPat = { - [@deriving (show({with_path: false}), sexp, yojson)] - type cls = - | Invalid - | EmptyHole - | MultiHole - | Var; - - include TermBase.UTPat; - - let rep_id = ({ids, _}) => { - assert(ids != []); - List.hd(ids); - }; - - let hole = (tms: list(any)) => - switch (tms) { - | [] => EmptyHole - | [_, ..._] => MultiHole(tms) - }; - - let cls_of_term: term => cls = - fun - | Invalid(_) => Invalid - | EmptyHole => EmptyHole - | MultiHole(_) => MultiHole - | Var(_) => Var; - - let show_cls: cls => string = - fun - | Invalid => "Invalid type alias" - | MultiHole => "Broken type alias" - | EmptyHole => "Empty type alias hole" - | Var => "Type alias"; -}; - module UPat = { [@deriving (show({with_path: false}), sexp, yojson)] type cls = diff --git a/src/haz3lcore/statics/TermBase.re b/src/haz3lcore/statics/TermBase.re index 65d2ad7134..55f77da428 100644 --- a/src/haz3lcore/statics/TermBase.re +++ b/src/haz3lcore/statics/TermBase.re @@ -400,16 +400,12 @@ and UTyp: { | Tuple(list(t)) | Parens(t) | Ap(t, t) -<<<<<<< HEAD | Sum(list(variant)) + | Forall(UTPat.t, t) + | Rec(UTPat.t, t) and variant = | Variant(Constructor.t, list(Id.t), option(t)) | BadEntry(t) -======= - | USum(list(t)) - | Forall(UTPat.t, t) - | Rec(UTPat.t, t) ->>>>>>> 4c7587694 (merge in poly-adt) and t = { ids: list(Id.t), term, @@ -431,16 +427,12 @@ and UTyp: { | Tuple(list(t)) | Parens(t) | Ap(t, t) -<<<<<<< HEAD | Sum(list(variant)) + | Forall(UTPat.t, t) + | Rec(UTPat.t, t) and variant = | Variant(Constructor.t, list(Id.t), option(t)) | BadEntry(t) -======= - | USum(list(t)) - | Forall(UTPat.t, t) - | Rec(UTPat.t, t) ->>>>>>> 4c7587694 (merge in poly-adt) and t = { ids: list(Id.t), term, diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index fcc763efd7..683764fcb4 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -53,7 +53,7 @@ module rec Typ: { let join_type_provenance: (type_provenance, type_provenance) => type_provenance; let matched_arrow: t => (t, t); - let matched_forall: t => t; + let matched_forall: t => (string, t); let matched_prod: (int, t) => list(t); let matched_cons: t => (t, t); let matched_list: t => t; @@ -136,7 +136,7 @@ module rec Typ: { | Forall(t, ty) => (t, ty) | Unknown(prov) => ("matched_forall", Unknown(prov)) | _ => ("matched_forall", Unknown(Internal)); /* TODO: Might need to be fresh? */ - + let matched_prod: (int, t) => list(t) = length => fun @@ -248,8 +248,8 @@ module rec Typ: { ) | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) - | Forall({item: inside, name: n}) => [] /* free_vars(~bound=[x, ...bound], ty) */ - /* TODO: unclear how to finish this until Typ is fully rebased. */ + | Forall(x, ty) => free_vars(~bound=[x, ...bound], ty) + /* TODO: check that these are correct. */ }; /* Lattice join on types. This is a LUB join in the hazel2 @@ -297,10 +297,10 @@ module rec Typ: { let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); Rec(x1, ty_body); - | (Forall({item: t1, name}), Forall({item: t2, _})) => + | (Forall(name, t1), Forall(_, t2)) => /* See note above in Rec case */ - switch (join(Ctx.add_abstract(ctx, name, -1), t1, t2)) { - | Some(t) => Some(Forall({item: t, name})) + switch (join(~resolve, ~fix, Ctx.extend_dummy_tvar(ctx, name), t1, t2)) { + | Some(t) => Some(Forall(name, t)) | None => None } | (Rec(_), _) => None @@ -632,35 +632,33 @@ and Kind: { type t = | Singleton(Typ.t) | Abstract; - -/* Is not needed as not using debrujin indices */ -/* - let rec incr = (ty: t, i: int): t => { - switch (ty) { - | Var({item: Some(j), name}) => Var({item: Some(i + j), name}) - | Var(_) => ty - | List(ty) => List(incr(ty, i)) - | Arrow(ty1, ty2) => Arrow(incr(ty1, i), incr(ty2, i)) - | Sum(map) => - Sum( - VarMap.map( - ((_, ty)) => - switch (ty) { - | Some(ty) => Some(incr(ty, i)) - | None => None - }, - map, - ), - ) - | Prod(tys) => Prod(List.map(ty => incr(ty, i), tys)) - | Rec({item, name}) => Rec({item: incr(item, i), name}) - | Forall({item, name}) => Forall({item: incr(item, i), name}) - | Int => Int - | Float => Float - | Bool => Bool - | String => String - | Unknown(_) => ty - }; -*/ - + /* Is not needed as not using debrujin indices */ + /* + let rec incr = (ty: t, i: int): t => { + switch (ty) { + | Var({item: Some(j), name}) => Var({item: Some(i + j), name}) + | Var(_) => ty + | List(ty) => List(incr(ty, i)) + | Arrow(ty1, ty2) => Arrow(incr(ty1, i), incr(ty2, i)) + | Sum(map) => + Sum( + VarMap.map( + ((_, ty)) => + switch (ty) { + | Some(ty) => Some(incr(ty, i)) + | None => None + }, + map, + ), + ) + | Prod(tys) => Prod(List.map(ty => incr(ty, i), tys)) + | Rec({item, name}) => Rec({item: incr(item, i), name}) + | Forall({item, name}) => Forall({item: incr(item, i), name}) + | Int => Int + | Float => Float + | Bool => Bool + | String => String + | Unknown(_) => ty + }; + */ }; From a0cf3d78ed29437afed418216ec0be88e611052a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 25 Aug 2023 15:41:47 -0400 Subject: [PATCH 030/229] Small fixes --- src/haz3lcore/statics/Statics.re | 7 ++++--- src/haz3lcore/statics/TypBase.re | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 79361f60c5..6c52178e2f 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -281,14 +281,15 @@ and uexp_to_info_map = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); (def, p_ana, m); } else { - let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + let p_syn_ty = p_syn.ty; + let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn_ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); let def_ctx = p_ana.ctx; - let (def_base2, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); + let (def_base2, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn_ty), def, m); let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { ty_p == Typ.Unknown(SynSwitch) && !Typ.eq(ty_fn1, ty_fn2) - ? ty_fn1 : ty_p; + ? ty_fn1 : Unknown(SynSwitch); }; let ana = switch ((def_base.ty, def_base2.ty), p_syn.ty) { diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index c5c7b936c3..a0f64badfd 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -152,7 +152,7 @@ module rec Typ: { default_arity => fun | Prod([_, ..._] as tys) => tys - | Unknown(_) as ty_unknown => List.init(default_arity, _ => ty_unknown) + | Unknown(_) as ty => matched_prod(default_arity, ty) | _ as ty => [ty]; let precedence = (ty: t): int => From 5f15dd0bf8c7bd113e0abef0fa0d08e47de224d7 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 25 Aug 2023 15:51:24 -0400 Subject: [PATCH 031/229] Simplified is_recursive --- src/haz3lcore/statics/Statics.re | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6c52178e2f..a925277ea3 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -51,17 +51,16 @@ let is_recursive = (ctx, p, def, syn: Typ.t) => { switch (Term.UPat.get_num_of_vars(p), Term.UExp.get_num_of_functions(def)) { | (Some(num_vars), Some(num_fns)) when num_vars != 0 && num_vars == num_fns => - switch (Typ.weak_head_normalize(ctx, syn)) { + switch (Typ.normalize(ctx, syn)) { | Unknown(_) => true | Arrow(_) when num_vars == 1 => true | Prod(syns) when List.length(syns) == num_vars => syns - |> List.for_all(syn => - switch (Typ.weak_head_normalize(ctx, syn)) { - | Unknown(_) + |> List.for_all( + fun + | Typ.Unknown(_) | Arrow(_) => true - | _ => false - } + | _ => false, ) | _ => false } From 7337f8fb899d96a05dbe1a072f7162b332844a27 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 25 Aug 2023 16:46:03 -0400 Subject: [PATCH 032/229] Resolving issues in Statics and Elaborator. --- src/haz3lcore/dynamics/Elaborator.re | 14 ++---- src/haz3lcore/statics/Kind.re | 4 -- src/haz3lcore/statics/Statics.re | 72 +++++++++++++++------------- 3 files changed, 41 insertions(+), 49 deletions(-) delete mode 100644 src/haz3lcore/statics/Kind.re diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 46eca8d3c0..926355d411 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -41,11 +41,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => switch (self_ty) { | Unknown(prov) => /* ? |> forall _. ? */ - DHExp.cast( - d, - Unknown(prov), - Forall({item: Unknown(prov), name: "_"}), - ) + DHExp.cast(d, Unknown(prov), Forall("_", Unknown(prov))) | Forall(_) => d | _ => failwith("Elaborator.wrap: SynTypFun non-forall-type") } @@ -68,11 +64,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | TypFun(_) => switch (ana_ty) { | Unknown(prov) => - DHExp.cast( - d, - Forall({item: Unknown(prov), name: "grounded_forall"}), - ana_ty, - ) + DHExp.cast(d, Forall("grounded_forall", Unknown(prov)), ana_ty) | _ => d } | Tuple(ds) => @@ -86,7 +78,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => | TypAp(Constructor(_), _) | Constructor(_) => switch (ana_ty, self_ty) { - | (Unknown(prov), Rec({item: Sum(_), _})) + | (Unknown(prov), Rec(_, Sum(_))) | (Unknown(prov), Sum(_)) => DHExp.cast(d, self_ty, Unknown(prov)) | _ => d } diff --git a/src/haz3lcore/statics/Kind.re b/src/haz3lcore/statics/Kind.re deleted file mode 100644 index 21b1604440..0000000000 --- a/src/haz3lcore/statics/Kind.re +++ /dev/null @@ -1,4 +0,0 @@ -[@deriving (show({with_path: false}), sexp, yojson)] -type t = - | Singleton(Typ.t) - | Abstract; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index caa8545166..8b10e7118b 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -253,22 +253,22 @@ and uexp_to_info_map = ); | TypFun({term: Var(name), _} as utpat, body) => let mode_body = Mode.of_forall(mode); - let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - let ctx_body = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); - let (body, m_body) = go'(~ctx=ctx_body, ~mode=mode_body, body); - add( - ~self=Just(Forall({item: body.ty, name})), - ~free=body.free, - union_m([m_typat, m_body]), - ); + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + let ctx_body = + Ctx.extend_tvar( + ctx, + {name, id: Term.UTPat.rep_id(utpat), kind: Abstract}, + ); + let (body, m) = go'(~ctx=ctx_body, ~mode=mode_body, body, m); + add(~self=Just(Forall(name, body.ty)), ~co_ctx=body.co_ctx, m); | TypFun(utpat, body) => let mode_body = Mode.of_forall(mode); - let m_typat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - let (body, m_body) = go(~mode=mode_body, body); + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + let (body, m) = go(~mode=mode_body, body, m); add( - ~self=Just(Forall({item: body.ty, name: "expected_type_variable"})), - ~free=body.free, - union_m([m_typat, m_body]), + ~self=Just(Forall("expected_type_variable", body.ty)), + ~co_ctx=body.co_ctx, + m, ); | Let(p, def, body) => let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); @@ -372,10 +372,6 @@ and uexp_to_info_map = go'(~ctx, ~mode, body, m); let m = utyp_to_info_map(~ctx, ~ancestors, utyp, m) |> snd; add(~self=Just(ty_body), ~co_ctx, m); - | _ => - let (Info.{free, ty: ty_body, _}, m_body) = go'(~ctx, ~mode, body); - let m_typ = utyp_to_info_map(~ctx, ~ancestors, utyp) |> snd; - add(~self=Just(ty_body), ~free, union_m([m_typat, m_body, m_typ])); }; }; } @@ -514,45 +510,53 @@ and utyp_to_info_map = (m, []), variants, ); - add(union_m(ms)); + add(m); | Forall({term: Var(name), _} as utpat, tbody) => - let body_ctx = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); + let body_ctx = + Ctx.extend_tvar( + ctx, + {name, id: Term.UTPat.rep_id(utpat), kind: Abstract}, + ); let m = utyp_to_info_map( tbody, ~ctx=body_ctx, ~ancestors, ~expects=TypeExpected, + m, ) |> snd; - let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - add(union_m([m, m_tpat])); // TODO: check with andrew + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + add(m); // TODO: check with andrew | Forall(utpat, tbody) => let m = - utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; - let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - add(union_m([m, m_tpat])); // TODO: check with andrew + utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected, m) + |> snd; + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + add(m); // TODO: check with andrew | Rec({term: Var(name), _} as utpat, tbody) => - let body_ctx = Ctx.add_abstract(ctx, name, Term.UTPat.rep_id(utpat)); + let body_ctx = + Ctx.extend_tvar( + ctx, + {name, id: Term.UTPat.rep_id(utpat), kind: Abstract}, + ); let m = utyp_to_info_map( tbody, ~ctx=body_ctx, ~ancestors, ~expects=TypeExpected, + m, ) |> snd; - let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - add(union_m([m, m_tpat])); // TODO: check with andrew + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + add(m); // TODO: check with andrew | Rec(utpat, tbody) => let m = - utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected) |> snd; - let m_tpat = utpat_to_info_map(~ctx, ~ancestors, utpat) |> snd; - add(union_m([m, m_tpat])); // TODO: check with andrew - | MultiHole(tms) => - let (_, ms) = - tms |> List.map(any_to_info_map(~ctx, ~ancestors)) |> List.split; - add(union_m(ms)); + utyp_to_info_map(tbody, ~ctx, ~ancestors, ~expects=TypeExpected, m) + |> snd; + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + add(m); // TODO: check with andrew }; } and utpat_to_info_map = From d78057e057a7a9518c67f259cb8527ef4ec2a935 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 25 Aug 2023 16:46:46 -0400 Subject: [PATCH 033/229] Edit constructors in frontend. --- src/haz3lweb/view/CursorInspector.re | 4 +--- src/haz3lweb/view/Kind.re | 2 +- src/haz3lweb/view/Type.re | 6 +++--- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 3 +-- src/haz3lweb/view/dhcode/layout/HTypDoc.re | 6 +++--- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index e97934b72d..1419aa81c1 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -138,7 +138,7 @@ let typ_ok_view = (cls: Term.Cls.t, ok: Info.ok_typ) => Type.view(ty_lookup), ] | Variant(name, sum_ty) => [ - Type.view(Var({name, item: None})), + Type.view(Var(name)), text("is a sum type constuctor of type"), Type.view(sum_ty), ] @@ -146,8 +146,6 @@ let typ_ok_view = (cls: Term.Cls.t, ok: Info.ok_typ) => text("An incomplete sum type constuctor of type"), Type.view(sum_ty), ] - | Variant(name, _sum_ty) => [Type.view(Var(name))] - | VariantIncomplete(_sum_ty) => [text("is incomplete")] }; let typ_err_view = (ok: Info.error_typ) => diff --git a/src/haz3lweb/view/Kind.re b/src/haz3lweb/view/Kind.re index f84672515c..148336e1c2 100644 --- a/src/haz3lweb/view/Kind.re +++ b/src/haz3lweb/view/Kind.re @@ -2,7 +2,7 @@ open Virtual_dom.Vdom; open Node; open Util.Web; -let view = (kind: Haz3lcore.Kind.t): Node.t => +let view = (kind: Haz3lcore.TypBase.Kind.t): Node.t => switch (kind) { | Singleton(ty) => div_c("kind-view", [Type.view(ty)]) | Abstract => div_c("kind-view", [text("Type")]) diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index 290eb81f61..e3afd602bb 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -33,13 +33,13 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Float => ty_view("Float", "Float") | String => ty_view("String", "String") | Bool => ty_view("Bool", "Bool") - | Var({name, _}) => ty_view("Var", name) - | Rec({item: t, name}) => + | Var(name) => ty_view("Var", name) + | Rec(name, t) => div( ~attr=clss(["typ-view", "Rec"]), [text("Rec " ++ name ++ ". "), view_ty(t)], ) - | Forall({item: t, name}) => + | Forall(name, t) => div( ~attr=clss(["typ-view", "Forall"]), [text("Forall " ++ name ++ ". "), view_ty(t)], diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 32780da431..cc14be633a 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -269,8 +269,7 @@ let rec mk = ]), mk_cast(go(~enforce_inline=false, dbody)), ]); - | FailedCast(Cast(d, ty1, ty2), ty2', ty3) - when Typ.eq_syntactic(ty2, ty2') => + | FailedCast(Cast(d, ty1, ty2), ty2', ty3) when Typ.eq(ty2, ty2') => let (d_doc, _) = go'(d); let cast_decoration = hcats([ diff --git a/src/haz3lweb/view/dhcode/layout/HTypDoc.re b/src/haz3lweb/view/dhcode/layout/HTypDoc.re index bff18b7240..2552da95e5 100644 --- a/src/haz3lweb/view/dhcode/layout/HTypDoc.re +++ b/src/haz3lweb/view/dhcode/layout/HTypDoc.re @@ -50,7 +50,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { | Float => (text("Float"), parenthesize) | Bool => (text("Bool"), parenthesize) | String => (text("String"), parenthesize) - | Var({name, _}) => (text(name), parenthesize) + | Var(name) => (text(name), parenthesize) | List(ty) => ( hcats([ mk_delim("["), @@ -106,7 +106,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { ) |> hcats; (center, true); - | Rec({item: ty, name}) => ( + | Rec(name, ty) => ( hcats([ text("Rec " ++ name ++ ".{"), ( @@ -118,7 +118,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { ]), parenthesize, ) - | Forall({item: ty, name}) => ( + | Forall(name, ty) => ( hcats([ text("Forall " ++ name ++ ".{"), ( From 06cbf1d3f75e91333994ebd757bbe7139659c5f4 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 25 Aug 2023 17:32:35 -0400 Subject: [PATCH 034/229] Change dhexp substitution to use binding names rather than debrujin. --- src/haz3lcore/dynamics/Evaluator.re | 95 +++++++++++++---------------- src/haz3lcore/statics/Term.re | 6 ++ 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index 24eaeaa8f8..c7fcf624bb 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -25,9 +25,7 @@ let grounded_Arrow = NotGroundOrHole(Arrow(Unknown(Internal), Unknown(Internal))); // TODO (typfun): Maybe the Forall should allow a hole in the variable position? let grounded_Forall = - NotGroundOrHole( - Forall({item: Unknown(Internal), name: "grounded_forall"}), - ); + NotGroundOrHole(Forall("grounded_forall", Unknown(Internal))); let grounded_Prod = length => NotGroundOrHole(Prod(ListUtil.replicate(length, Typ.Unknown(Internal)))); let grounded_Sum = (sm: Typ.sum_map): ground_cases => { @@ -51,7 +49,7 @@ let rec ground_cases_of = (ty: Typ.t): ground_cases => { | Var(_) | Rec(_) | Arrow(Unknown(_), Unknown(_)) - | Forall({item: Unknown(_), name: _}) + | Forall(_, Unknown(_)) | List(Unknown(_)) => Ground | Prod(tys) => if (List.for_all( @@ -184,8 +182,8 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | None => DoesNotMatch } - | (Ap(_, _), Cast(d, Sum(_) | Rec({item: Sum(_), _}), Unknown(_))) - | (Ap(_, _), Cast(d, Unknown(_), Sum(_) | Rec({item: Sum(_), _}))) => + | (Ap(_, _), Cast(d, Sum(_) | Rec(_, Sum(_)), Unknown(_))) + | (Ap(_, _), Cast(d, Unknown(_), Sum(_) | Rec(_, Sum(_)))) => matches(dp, d) | (Ap(_, _), _) => DoesNotMatch @@ -292,11 +290,7 @@ and matches_cast_Sum = matches(dp, DHExp.apply_casts(d', side_casts)) | _ => DoesNotMatch } - | Cast( - d', - Sum(sm1) | Rec({item: Sum(sm1), _}), - Sum(sm2) | Rec({item: Sum(sm2), _}), - ) => + | Cast(d', Sum(sm1) | Rec(_, Sum(sm1)), Sum(sm2) | Rec(_, Sum(sm2))) => switch (cast_sum_maps(sm1, sm2)) { | Some(castmap) => matches_cast_Sum(ctr, dp, d', [castmap, ...castmaps]) | None => DoesNotMatch @@ -638,26 +632,27 @@ let eval_bin_string_op = }; let rec ty_subst = - (~idx=0, exp, targ) + (s: Typ.t, x: TypVar.t, exp) : DHExp.t /* TODO: Maybe just keep error instead of recursing? */ => { open DH.DHExp; - let re = e2 => ty_subst(~idx, e2, targ); + let re = e2 => ty_subst(s, x, e2); + let t_re = ty => Typ.subst(s, x, ty); switch (exp) { - | Cast(t, t1, t2) => - Cast(re(t), Typ.subst(targ, ~x=idx, t1), Typ.subst(targ, ~x=idx, t2)) - | FixF(arg, ty, body) => FixF(arg, Typ.subst(targ, ~x=idx, ty), re(body)) - | Fun(arg, ty, body, var) => - Fun(arg, Typ.subst(targ, ~x=idx, ty), re(body), var) - | TypAp(tfun, ty) => TypAp(re(tfun), Typ.subst(targ, ~x=idx, ty)) - | ListLit(mv, mvi, lerr, t, lst) => - ListLit(mv, mvi, lerr, Typ.subst(targ, ~x=idx, t), List.map(re, lst)) - - | TypFun(utpat, body) => TypFun(utpat, ty_subst(~idx=idx + 1, body, targ)) - + | Cast(t, t1, t2) => Cast(re(t), t_re(t1), t_re(t2)) + | FixF(arg, ty, body) => FixF(arg, t_re(ty), re(body)) + | Fun(arg, ty, body, var) => Fun(arg, t_re(ty), re(body), var) + | TypAp(tfun, ty) => TypAp(re(tfun), t_re(ty)) + | ListLit(mv, mvi, t, lst) => + ListLit(mv, mvi, t_re(t), List.map(re, lst)) + | TypFun(utpat, body) => + switch (Term.UTPat.tyvar_of_utpat(utpat)) { + | Some(x') when x == x' => exp + | _ => TypFun(utpat, re(body)) + } | NonEmptyHole(errstat, mv, hid, t) => NonEmptyHole(errstat, mv, hid, re(t)) | InconsistentBranches(mv, hid, case) => - InconsistentBranches(mv, hid, ty_subst_case(~idx, case, targ)) + InconsistentBranches(mv, hid, ty_subst_case(s, x, case)) | Closure(ce, t) => Closure(ce, re(t)) | Sequence(t1, t2) => Sequence(re(t1), re(t2)) | Let(dhpat, t1, t2) => Let(dhpat, re(t1), re(t2)) @@ -668,32 +663,33 @@ let rec ty_subst = | BinFloatOp(op, t1, t2) => BinFloatOp(op, re(t1), re(t2)) | BinStringOp(op, t1, t2) => BinStringOp(op, re(t1), re(t2)) | Cons(t1, t2) => Cons(re(t1), re(t2)) + | ListConcat(t1, t2) => ListConcat(re(t1), re(t2)) | Tuple(args) => Tuple(List.map(re, args)) | Prj(t, n) => Prj(re(t), n) - | ConsistentCase(case) => ConsistentCase(ty_subst_case(~idx, case, targ)) + | ConsistentCase(case) => ConsistentCase(ty_subst_case(s, x, case)) | InvalidOperation(t, err) => InvalidOperation(re(t), err) | EmptyHole(_) | ExpandingKeyword(_, _, _) | FreeVar(_, _, _) | InvalidText(_, _, _) + | Constructor(_) | BoundVar(_) | TestLit(_) | BoolLit(_) | IntLit(_) | FloatLit(_) | StringLit(_) - | Tag(_) | FailedCast(_, _, _) => exp }; } //TODO: is this correct? //TODO: Inconsistent cases: need to check again for inconsistency? -and ty_subst_case = (~idx=0, Case(t, rules, n), targ) => +and ty_subst_case = (s, x, Case(t, rules, n)) => Case( - ty_subst(~idx, t, targ), + ty_subst(s, x, t), List.map( - (DHExp.Rule(dhpat, t)) => DHExp.Rule(dhpat, ty_subst(~idx, t, targ)), + (DHExp.Rule(dhpat, t)) => DHExp.Rule(dhpat, ty_subst(s, x, t)), rules, ), n, @@ -756,26 +752,23 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | TypAp(d1, tau) => let* r1 = evaluate(env, d1); switch (r1) { - | BoxedValue(Closure(closure_env, TypFun(_, d2))) => + | BoxedValue(Closure(closure_env, TypFun(utpat, d2))) => // TODO: Maybe additional cases to be done? - evaluate(closure_env, ty_subst(d2, tau)) - | BoxedValue( - Cast( - d1', - Forall({item: t, name: _}), - Forall({item: t', name: _}), - ), - ) - | Indet( - Cast( - d1', - Forall({item: t, name: _}), - Forall({item: t', name: _}), - ), - ) => + switch (Term.UTPat.tyvar_of_utpat(utpat)) { + | Some(tyvar) => evaluate(closure_env, ty_subst(tau, tyvar, d2)) + | None => + /* Treat a hole or invalid tyvar name as a unique type variable that doesn't appear anywhere else. Thus instantiating it at anything doesn't produce any substitutions. */ + evaluate(closure_env, d2) + } + | BoxedValue(Cast(d1', Forall(x, t), Forall(x', t'))) + | Indet(Cast(d1', Forall(x, t), Forall(x', t'))) => evaluate( env, - Cast(TypAp(d1', tau), Typ.subst(t, tau), Typ.subst(t', tau)), + Cast( + TypAp(d1', tau), + Typ.subst(tau, x, t), + Typ.subst(tau, x', t'), + ), ) | Indet(_) => r1 |> return | _ => failwith("InvalidBoxedTypFun: " ++ show(r1)) @@ -1132,7 +1125,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = /* by canonical forms, d1' must be of the form d ?> */ switch (d1') { | Cast(d1'', ty'', Unknown(_)) => - if (Typ.eq_syntactic(ty'', ty')) { + if (Typ.eq(ty'', ty')) { BoxedValue(d1'') |> return; } else { Indet(FailedCast(d1', ty, ty')) |> return; @@ -1154,7 +1147,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = BoxedValue(Cast(d1', ty, ty')) |> return | (NotGroundOrHole(_), NotGroundOrHole(_)) => /* they might be eq in this case, so remove cast if so */ - if (Typ.eq_syntactic(ty, ty')) { + if (Typ.eq(ty, ty')) { result |> return; } else { BoxedValue(Cast(d1', ty, ty')) |> return; @@ -1172,7 +1165,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = | (Hole, Ground) => switch (d1') { | Cast(d1'', ty'', Unknown(_)) => - if (Typ.eq_syntactic(ty'', ty')) { + if (Typ.eq(ty'', ty')) { Indet(d1'') |> return; } else { Indet(FailedCast(d1', ty, ty')) |> return; @@ -1194,7 +1187,7 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) = Indet(Cast(d1', ty, ty')) |> return | (NotGroundOrHole(_), NotGroundOrHole(_)) => /* it might be eq in this case, so remove cast if so */ - if (Typ.eq_syntactic(ty, ty')) { + if (Typ.eq(ty, ty')) { result |> return; } else { Indet(Cast(d1', ty, ty')) |> return; diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index b075c17c4c..c0418f8be3 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -53,6 +53,12 @@ module UTPat = { | MultiHole => "Broken type alias" | EmptyHole => "Empty type alias hole" | Var => "Type alias"; + + let tyvar_of_utpat = ({ids: _, term}) => + switch (term) { + | Var(x) => Some(x) + | _ => None + }; }; module UTyp = { From 749da41b91d36da460cf56933ff4bd731bc2bc3b Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 25 Aug 2023 17:50:40 -0400 Subject: [PATCH 035/229] Fix issue with looking up tvars in ctx. --- src/haz3lcore/statics/Info.re | 6 +++++- src/haz3lcore/statics/TypBase.re | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index af8aa33b15..ea96f63bc8 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -358,7 +358,11 @@ let status_typ = InHole(DuplicateConstructor(name)) | TypeExpected => switch (Ctx.is_alias(ctx, name)) { - | false => InHole(FreeTypeVariable(name)) + | false => + switch (Ctx.is_tvar(ctx, name)) { + | false => InHole(FreeTypeVariable(name)) + | true => NotInHole(Type(Var(name))) + } | true => NotInHole(TypeAlias(name, Typ.weak_head_normalize(ctx, ty))) } } diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 683764fcb4..15964f3f48 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -473,6 +473,7 @@ and Ctx: { let lookup_var: (t, string) => option(var_entry); let lookup_ctr: (t, string) => option(var_entry); let is_alias: (t, TypVar.t) => bool; + let is_tvar: (t, TypVar.t) => bool; let add_ctrs: (t, TypVar.t, Id.t, Typ.sum_map) => t; let subtract_prefix: (t, t) => option(t); let added_bindings: (t, t) => t; @@ -556,6 +557,12 @@ and Ctx: { | None => false }; + let is_tvar = (ctx: t, name: TypVar.t): bool => + switch (lookup_tvar(ctx, name)) { + | Some(_) => true + | None => false + }; + let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => List.map( ((ctr, typ)) => From 66870d3e4ac4b8dcbb338bc9a10955b7251429f7 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 25 Aug 2023 18:26:00 -0400 Subject: [PATCH 036/229] Fix error in alpha equiv --- src/haz3lcore/statics/TypBase.re | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 15964f3f48..2d6eed9553 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -199,11 +199,16 @@ module rec Typ: { /* Type Equality: At the moment, this coincides with alpha equivalence, but this will change when polymorphic types are implemented */ - let rec eq = (t1: t, t2: t): bool => { + let rec eq_internal = (n: int, t1: t, t2: t) => { switch (t1, t2) { - | (Rec(x1, t1), Rec(x2, t2)) => eq(t1, subst(Var(x1), x2, t2)) + | (Rec(x1, t1), Rec(x2, t2)) + | (Forall(x1, t1), Forall(x2, t2)) => + eq_internal( + n + 1, + subst(Var("@" ++ string_of_int(n)), x1, t1), + subst(Var("@" ++ string_of_int(n)), x2, t2), + ) | (Rec(_), _) => false - | (Forall(x1, t1), Forall(x2, t2)) => eq(t1, subst(Var(x1), x2, t2)) /* TODO: correct? */ | (Forall(_), _) => false | (Int, Int) => true | (Int, _) => false @@ -215,20 +220,23 @@ module rec Typ: { | (String, _) => false | (Unknown(_), Unknown(_)) => true | (Unknown(_), _) => false - | (Arrow(t1, t2), Arrow(t1', t2')) => eq(t1, t1') && eq(t2, t2') + | (Arrow(t1, t2), Arrow(t1', t2')) => + eq_internal(n, t1, t1') && eq_internal(n, t2, t2') | (Arrow(_), _) => false - | (Prod(tys1), Prod(tys2)) => List.equal(eq, tys1, tys2) + | (Prod(tys1), Prod(tys2)) => List.equal(eq_internal(n), tys1, tys2) | (Prod(_), _) => false - | (List(t1), List(t2)) => eq(t1, t2) + | (List(t1), List(t2)) => eq_internal(n, t1, t2) | (List(_), _) => false | (Sum(sm1), Sum(sm2)) => - ConstructorMap.equal(Option.equal(eq), sm1, sm2) + ConstructorMap.equal(Option.equal(eq_internal(n)), sm1, sm2) | (Sum(_), _) => false | (Var(n1), Var(n2)) => n1 == n2 | (Var(_), _) => false }; }; + let eq = (t1: t, t2: t): bool => eq_internal(0, t1, t2); + let rec free_vars = (~bound=[], ty: t): list(Var.t) => switch (ty) { | Unknown(_) From e63913db8475a6b226218afd8620332a17f47a99 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 26 Aug 2023 14:24:26 -0400 Subject: [PATCH 037/229] Fix typechecking with mismatching type variable names. --- src/haz3lcore/statics/Mode.re | 9 ++++++--- src/haz3lcore/statics/Statics.re | 4 ++-- src/haz3lcore/statics/TypBase.re | 12 ++++++------ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index 267f465abb..05300ca116 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -46,14 +46,17 @@ let of_arrow = (ctx: Ctx.t, mode: t): (t, t) => |> TupleUtil.map2(ana) }; -let of_forall = (mode: t): t => +let of_forall = (name_opt: option(TypVar.t), mode: t): t => switch (mode) { | Syn | SynFun | SynTypFun => Syn | Ana(ty) => - let (_, item) = Typ.matched_forall(ty); - Ana(item); + let (name_expected, item) = Typ.matched_forall(ty); + switch (name_opt) { + | Some(name) => Ana(Typ.subst(Var(name), name_expected, item)) + | None => Ana(item) + }; }; let of_prod = (ctx: Ctx.t, mode: t, length): list(t) => diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 8b10e7118b..2f5ef952a8 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -252,7 +252,7 @@ and uexp_to_info_map = m, ); | TypFun({term: Var(name), _} as utpat, body) => - let mode_body = Mode.of_forall(mode); + let mode_body = Mode.of_forall(Some(name), mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; let ctx_body = Ctx.extend_tvar( @@ -262,7 +262,7 @@ and uexp_to_info_map = let (body, m) = go'(~ctx=ctx_body, ~mode=mode_body, body, m); add(~self=Just(Forall(name, body.ty)), ~co_ctx=body.co_ctx, m); | TypFun(utpat, body) => - let mode_body = Mode.of_forall(mode); + let mode_body = Mode.of_forall(None, mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; let (body, m) = go(~mode=mode_body, body, m); add( diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 2d6eed9553..04094e5ad7 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -185,7 +185,7 @@ module rec Typ: { | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) | Rec(y, ty) => Rec(y, subst(s, x, ty)) | Forall(y, ty) when TypVar.eq(x, y) => Forall(y, ty) - | Forall(y, ty) => Forall(y, subst(s, x, ty)) + | Forall(y, ty) => Forall(y, subst(s, x, ty)) /* TODO: Need to implement capture avoiding subst */ | List(ty) => List(subst(s, x, ty)) | Var(y) => TypVar.eq(x, y) ? s : Var(y) }; @@ -305,12 +305,12 @@ module rec Typ: { let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); Rec(x1, ty_body); - | (Forall(name, t1), Forall(_, t2)) => + | (Forall(x1, ty1), Forall(x2, ty2)) => /* See note above in Rec case */ - switch (join(~resolve, ~fix, Ctx.extend_dummy_tvar(ctx, name), t1, t2)) { - | Some(t) => Some(Forall(name, t)) - | None => None - } + let ctx = Ctx.extend_dummy_tvar(ctx, x1); + let+ ty_body = + join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); + Forall(x1, ty_body); | (Rec(_), _) => None | (Forall(_), _) => None | (Int, Int) => Some(Int) From c3f44b43fb026cd6b649c1fbd55687a23395ddd7 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 26 Aug 2023 15:08:37 -0400 Subject: [PATCH 038/229] Implement capture avoiding substitution. --- src/haz3lcore/statics/TypBase.re | 62 ++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 04094e5ad7..98e018234b 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -172,6 +172,36 @@ module rec Typ: { | Arrow(_, _) => precedence_Arrow }; + let rec free_vars = (~bound=[], ty: t): list(Var.t) => + switch (ty) { + | Unknown(_) + | Int + | Float + | Bool + | String => [] + | Var(v) => List.mem(v, bound) ? [] : [v] + | List(ty) => free_vars(~bound, ty) + | Arrow(t1, t2) => free_vars(~bound, t1) @ free_vars(~bound, t2) + | Sum(sm) => + ListUtil.flat_map( + fun + | None => [] + | Some(typ) => free_vars(~bound, typ), + List.map(snd, sm), + ) + | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) + | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) + | Forall(x, ty) => free_vars(~bound=[x, ...bound], ty) + /* TODO: check that these are correct. */ + }; + + let var_count = ref(0); + let fresh_var = () => { + let x = var_count^; + var_count := x + 1; + "@" ++ string_of_int(x); + }; + let rec subst = (s: t, x: TypVar.t, ty: t) => { switch (ty) { | Int => Int @@ -185,7 +215,10 @@ module rec Typ: { | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) | Rec(y, ty) => Rec(y, subst(s, x, ty)) | Forall(y, ty) when TypVar.eq(x, y) => Forall(y, ty) - | Forall(y, ty) => Forall(y, subst(s, x, ty)) /* TODO: Need to implement capture avoiding subst */ + | Forall(y, ty) when List.mem(y, free_vars(s)) => + let fresh = fresh_var(); + Forall(fresh, subst(s, x, subst(Var(fresh), y, ty))); + | Forall(y, ty) => Forall(y, subst(s, x, ty)) | List(ty) => List(subst(s, x, ty)) | Var(y) => TypVar.eq(x, y) ? s : Var(y) }; @@ -205,8 +238,8 @@ module rec Typ: { | (Forall(x1, t1), Forall(x2, t2)) => eq_internal( n + 1, - subst(Var("@" ++ string_of_int(n)), x1, t1), - subst(Var("@" ++ string_of_int(n)), x2, t2), + subst(Var("=" ++ string_of_int(n)), x1, t1), + subst(Var("=" ++ string_of_int(n)), x2, t2), ) | (Rec(_), _) => false | (Forall(_), _) => false @@ -237,29 +270,6 @@ module rec Typ: { let eq = (t1: t, t2: t): bool => eq_internal(0, t1, t2); - let rec free_vars = (~bound=[], ty: t): list(Var.t) => - switch (ty) { - | Unknown(_) - | Int - | Float - | Bool - | String => [] - | Var(v) => List.mem(v, bound) ? [] : [v] - | List(ty) => free_vars(~bound, ty) - | Arrow(t1, t2) => free_vars(~bound, t1) @ free_vars(~bound, t2) - | Sum(sm) => - ListUtil.flat_map( - fun - | None => [] - | Some(typ) => free_vars(~bound, typ), - List.map(snd, sm), - ) - | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) - | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) - | Forall(x, ty) => free_vars(~bound=[x, ...bound], ty) - /* TODO: check that these are correct. */ - }; - /* Lattice join on types. This is a LUB join in the hazel2 sense in that any type dominates Unknown. The optional resolve parameter specifies whether, in the case of a type From 4ef0651d03f027f4e191db38ce74a7efc5560de0 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 26 Aug 2023 15:16:49 -0400 Subject: [PATCH 039/229] Add capture avoiding binding to recursive types. --- src/haz3lcore/statics/TypBase.re | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 98e018234b..b089ee0fc4 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -213,6 +213,9 @@ module rec Typ: { | Prod(tys) => Prod(List.map(subst(s, x), tys)) | Sum(sm) => Sum(ConstructorMap.map(Option.map(subst(s, x)), sm)) | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) + | Rec(y, ty) when List.mem(y, free_vars(s)) => + let fresh = fresh_var(); + Rec(fresh, subst(s, x, subst(Var(fresh), y, ty))); | Rec(y, ty) => Rec(y, subst(s, x, ty)) | Forall(y, ty) when TypVar.eq(x, y) => Forall(y, ty) | Forall(y, ty) when List.mem(y, free_vars(s)) => From 45751eea66f3346c664231af64a06eb03f31f69b Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 9 Jul 2023 21:54:32 +0800 Subject: [PATCH 040/229] Add some function from injection paper. --- src/haz3lcore/dynamics/Incon.re | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/haz3lcore/dynamics/Incon.re diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re new file mode 100644 index 0000000000..a5d4b8ded2 --- /dev/null +++ b/src/haz3lcore/dynamics/Incon.re @@ -0,0 +1,39 @@ +let rec matches = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (_, Var(_)) => true + | (_, Wild) => true + | (BoolLit(x), BoolLit(y)) => x == y + | (IntLit(x), IntLit(y)) => x == y + | (FloatLit(x), FloatLit(y)) => x == y + | (StringLit(x), StringLit(y)) => x == y + | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) + // I don't know how to extend the algorithm for projection into that of list or tuples. + | (_, _) => false + }; + +let rec is_val = (e: DHExp.t): bool => + switch (e) { + | BoolLit(_) + | IntLit(_) + | StringLit(_) + | Fun(_, _, _, _) + | ListLit(_, _, _, _, []) + | Tuple([]) => true + | ListLit(_, _, _, _, inner) + | Tuple(inner) => + List.fold_left((last_val, e) => last_val && is_val(e), true, inner) + | BinBoolOp(_, e1, e2) + | BinIntOp(_, e1, e2) + | BinFloatOp(_, e1, e2) + | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false + | Inj(_, _, e) => is_val(e) + | _ => false + }; + +let rec is_indet = (e: DHExp.t): bool => + switch (e) { + | EmptyHole(_, _) => true + | NonEmptyHole(_, _, _, e) => is_final(e) + | _ => false + } +and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); From 0b768ecd1b290003e7e371c0f6dde5042d6f754d Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 16 Jul 2023 11:59:57 +0800 Subject: [PATCH 041/229] Finished implementing algorithms from P8. --- src/haz3lcore/dynamics/Incon.re | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index a5d4b8ded2..2d403e1174 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -7,10 +7,35 @@ let rec matches = (e: DHExp.t, p: DHPat.t): bool => | (FloatLit(x), FloatLit(y)) => x == y | (StringLit(x), StringLit(y)) => x == y | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know how to extend the algorithm for projection into that of list or tuples. + // I don't know if my algorithm is correct or not. + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => true + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) | (_, _) => false }; +let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (BoolLit(x), BoolLit(y)) => x != y + | (IntLit(x), IntLit(y)) => x != y + | (FloatLit(x), FloatLit(y)) => x != y + | (StringLit(x), StringLit(y)) => x != y + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => false + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) + | (Inj(_, side1, x), Inj(side2, y)) => + side1 != side2 || does_not_match(x, y) + | (_, _) => false + }; + +// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. +let indet_match = (e: DHExp.t, p: DHPat.t): bool => + !(matches(e, p) || does_not_match(e, p)); + let rec is_val = (e: DHExp.t): bool => switch (e) { | BoolLit(_) From 7d9b905f098e422e915f1e249e2c4d332bd345cc Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Fri, 21 Jul 2023 18:10:34 +0800 Subject: [PATCH 042/229] Translating part of old Constraint.re into this version. --- src/haz3lcore/dynamics/Constraint.re | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/haz3lcore/dynamics/Constraint.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re new file mode 100644 index 0000000000..c94c805f29 --- /dev/null +++ b/src/haz3lcore/dynamics/Constraint.re @@ -0,0 +1,41 @@ +open Sexplib.Std; + +[@deriving sexp] +type t = + | Truth + | Falsity + | Hole + | Int(int) + | NotInt(int) + | Float(float) + | NotFloat(float) + | String(string) + | NotString(string) + | And(t, t) + | Or(t, t) + | InjL(t) + | InjR(t) + | List(list(t)); + +// How to replace this function? +let rec constrains = (c: t, ty: HTyp.t): bool => + switch (c, ty) { + // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { + | (Truth, _) + | (Falsity, _) + | (Hole, _) => true + | (Int(_) | NotInt(_), Int) => true + | (Int(_) | NotInt(_), _) => false + | (Float(_) | NotFloat(_), Float) => true + | (Float(_) | NotFloat(_), _) => false + | (String(_) | NotString(_), String) => true + | (String(_) | NotString(_), _) => false + | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + | (InjL(_), _) => false + | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(_), _) => false + | (List(c), ty) => + List.fold_left((last, x) => last && constrains(x, ty), true, c) + }; From 90d8e980605cfda48b57323c779de544a75fbf6c Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Tue, 1 Aug 2023 21:16:36 +0800 Subject: [PATCH 043/229] Rebase, Part 1. --- src/haz3lcore/dynamics/InvalidOperationError.re | 4 ++++ src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index ce8c94e888..858e7b0757 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -5,6 +5,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel + | InvalidIntOfString + | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -14,5 +16,7 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" + | InvalidIntOfString => "Error: Invalid String to Int Conversion" + | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 2dc53757b5..ead18ee4ff 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -179,7 +179,7 @@ let rec mk = | BoolLit(b) => DHDoc_common.mk_BoolLit(b) | IntLit(n) => DHDoc_common.mk_IntLit(n) | FloatLit(f) => DHDoc_common.mk_FloatLit(f) - | StringLit(s) => DHDoc_common.mk_StringLit(s) + | StringLit(s) => DHDoc_common.mk_StringLit("\"" ++ s ++ "\"") | TestLit(_) => Doc.text(ExpandingKeyword.to_string(Test)) | Sequence(d1, d2) => let (doc1, doc2) = (go'(d1), go'(d2)); From 8c5a214dd13c7420226ce74e017e4979b58b8707 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Mon, 7 Aug 2023 22:23:42 +0800 Subject: [PATCH 044/229] Rebase, Part 2. --- src/haz3lcore/dynamics/Constraint.re | 112 +++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c94c805f29..c8e4bee946 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -18,9 +18,11 @@ type t = | List(list(t)); // How to replace this function? -let rec constrains = (c: t, ty: HTyp.t): bool => - switch (c, ty) { - // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { +let rec constrains = (c: t, ty: Typ.t): bool => + switch ( + c, + Typ.weak_head_normalize(Builtins.ctx(Builtins.Pervasives.builtins), ty), + ) { | (Truth, _) | (Falsity, _) | (Hole, _) => true @@ -32,10 +34,110 @@ let rec constrains = (c: t, ty: HTyp.t): bool => | (String(_) | NotString(_), _) => false | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) - | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + // Treates sum as if it is left associative + | (InjL(c1), Sum(map)) => + switch (List.hd(map)) { + | (_, Some(ty1)) => constrains(c1, ty1) + | _ => false + } | (InjL(_), _) => false - | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(c2), Sum(map)) => + switch (List.tl(map)) { + | [] => false + | [(_, Some(ty2))] => constrains(c2, ty2) + | map' => constrains(c2, Sum(map')) + } | (InjR(_), _) => false | (List(c), ty) => List.fold_left((last, x) => last && constrains(x, ty), true, c) }; + +let rec or_constraints = (lst: list(t)): t => + switch (lst) { + | [] => failwith("should have at least one constraint") + | [xi] => xi + | [xi, ...xis] => Or(xi, or_constraints(xis)) + }; + +let rec dual = (c: t): t => + switch (c) { + | Truth => Falsity + | Falsity => Truth + | Hole => Hole + | Int(n) => NotInt(n) + | NotInt(n) => Int(n) + | Float(n) => NotFloat(n) + | NotFloat(n) => Float(n) + | String(n) => NotString(n) + | NotString(n) => String(n) + | And(c1, c2) => Or(dual(c1), dual(c2)) + | Or(c1, c2) => And(dual(c1), dual(c2)) + | InjL(c1) => Or(InjL(dual(c1)), InjR(Truth)) + | InjR(c2) => Or(InjR(dual(c2)), InjL(Truth)) + // Thought: generate all combinations of ways to dual the list (2^n - 1), and connect them with or + | List(l) => + let permutation = List.map(l' => List(l'), List.tl(permutate(l))); + // ``Or'' is associative, so I try to use this way to simplify it + or_constraints(permutation); + } +and permutate = (l: list(t)): list(list(t)) => + switch (l) { + | [] => [[]] + | [hd, ...tl] => + let result_tl = permutate(tl); + List.map(l' => [hd, ...l'], result_tl) + @ List.map(l' => [dual(hd), ...l'], result_tl); + }; + +/** substitute Truth for Hole */ +let rec truify = (c: t): t => + switch (c) { + | Hole => Truth + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(truify(c1), truify(c2)) + | Or(c1, c2) => Or(truify(c1), truify(c2)) + | InjL(c) => InjL(truify(c)) + | InjR(c) => InjR(truify(c)) + | List(l) => List.map(c => truify(c), l) + }; + +/** substitute Falsity for Hole */ +let rec falsify = (c: t): t => + switch (c) { + | Hole => Falsity + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(falsify(c1), falsify(c2)) + | Or(c1, c2) => Or(falsify(c1), falsify(c2)) + | InjL(c) => InjL(falsify(c)) + | InjR(c) => InjR(falsify(c)) + | List(l) => List.map(c => falsify(c), l) + }; + +let unwrapL = + fun + | InjL(c) => c + | _ => failwith("input can only be InjL(_)"); + +let unwrapR = + fun + | InjR(c) => c + | _ => failwith("input can only be InjR(_)"); + +let unwrap_list = + fun + | List(l) => l + | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file From b0b6ce66ead2e98d98203d656be14cee934e59fe Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 16 Aug 2023 18:38:12 +0800 Subject: [PATCH 045/229] Ported `Incon.re` and `Sets.re`. --- src/haz3lcore/dynamics/Constraint.re | 6 +- src/haz3lcore/dynamics/Incon.re | 296 +++++++++++++++++++++------ src/haz3lcore/dynamics/Sets.re | 23 +++ 3 files changed, 265 insertions(+), 60 deletions(-) create mode 100644 src/haz3lcore/dynamics/Sets.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c8e4bee946..1388e2fde6 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -105,7 +105,7 @@ let rec truify = (c: t): t => | Or(c1, c2) => Or(truify(c1), truify(c2)) | InjL(c) => InjL(truify(c)) | InjR(c) => InjR(truify(c)) - | List(l) => List.map(c => truify(c), l) + | List(l) => List(List.map(c => truify(c), l)) }; /** substitute Falsity for Hole */ @@ -124,7 +124,7 @@ let rec falsify = (c: t): t => | Or(c1, c2) => Or(falsify(c1), falsify(c2)) | InjL(c) => InjL(falsify(c)) | InjR(c) => InjR(falsify(c)) - | List(l) => List.map(c => falsify(c), l) + | List(l) => List(List.map(c => falsify(c), l)) }; let unwrapL = @@ -140,4 +140,4 @@ let unwrapR = let unwrap_list = fun | List(l) => l - | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file + | _ => failwith("input can only be List([_, ..._])"); diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 2d403e1174..204d181cb6 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -1,64 +1,246 @@ -let rec matches = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (_, Var(_)) => true - | (_, Wild) => true - | (BoolLit(x), BoolLit(y)) => x == y - | (IntLit(x), IntLit(y)) => x == y - | (FloatLit(x), FloatLit(y)) => x == y - | (StringLit(x), StringLit(y)) => x == y - | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know if my algorithm is correct or not. - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => true - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) - | (_, _) => false +open Sets; + +let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { + let (int_set, not_int_list) = + List.fold_left( + ((int_set, not_int_list), xi: Constraint.t) => + switch (xi) { + | Int(n) => (IntSet.add(n, int_set), not_int_list) + | NotInt(n) => (int_set, [n, ...not_int_list]) + | _ => failwith("input can only be Int | NotInt") + }, + (IntSet.empty, []), + xis, + ); + if (IntSet.cardinal(int_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + IntSet.mem(n, int_set); + }, + false, + not_int_list, + ); }; +}; -let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (BoolLit(x), BoolLit(y)) => x != y - | (IntLit(x), IntLit(y)) => x != y - | (FloatLit(x), FloatLit(y)) => x != y - | (StringLit(x), StringLit(y)) => x != y - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => false - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) - | (Inj(_, side1, x), Inj(side2, y)) => - side1 != side2 || does_not_match(x, y) - | (_, _) => false +let is_inconsistent_float = (xis: list(Constraint.t)): bool => { + let (float_set, not_float_list) = + List.fold_left( + ((float_set, not_float_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (FloatSet.add(n, float_set), not_float_list) + | NotFloat(n) => (float_set, [n, ...not_float_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (FloatSet.empty, []), + xis, + ); + if (FloatSet.cardinal(float_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + FloatSet.mem(n, float_set); + }, + false, + not_float_list, + ); }; +}; -// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. -let indet_match = (e: DHExp.t, p: DHPat.t): bool => - !(matches(e, p) || does_not_match(e, p)); +let is_inconsistent_string = (xis: list(Constraint.t)): bool => { + let (string_set, not_string_list) = + List.fold_left( + ((string_set, not_string_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (StringSet.add(n, string_set), not_string_list) + | NotFloat(n) => (string_set, [n, ...not_string_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (StringSet.empty, []), + xis, + ); + if (StringSet.cardinal(string_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + StringSet.mem(n, string_set); + }, + false, + not_string_list, + ); + }; +}; -let rec is_val = (e: DHExp.t): bool => - switch (e) { - | BoolLit(_) - | IntLit(_) - | StringLit(_) - | Fun(_, _, _, _) - | ListLit(_, _, _, _, []) - | Tuple([]) => true - | ListLit(_, _, _, _, inner) - | Tuple(inner) => - List.fold_left((last_val, e) => last_val && is_val(e), true, inner) - | BinBoolOp(_, e1, e2) - | BinIntOp(_, e1, e2) - | BinFloatOp(_, e1, e2) - | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false - | Inj(_, _, e) => is_val(e) - | _ => false +let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => + switch (xis) { + | [] => false + | [xi, ...xis'] => + switch (xi) { + | Truth => is_inconsistent(~may, xis') + | Falsity => true + | Hole => may ? true : is_inconsistent(~may, xis') + | And(xi1, xi2) => is_inconsistent(~may, [xi1, xi2, ...xis']) + | Or(xi1, xi2) => + is_inconsistent(~may, [xi1, ...xis']) + && is_inconsistent(~may, [xi2, ...xis']) + | InjL(_) => + if (List.exists( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + ) + ) { + | (injLs, []) => + let unwrap = List.map(Constraint.unwrapL, injLs); + is_inconsistent(~may, unwrap); + | (injLs, other) => is_inconsistent(~may, other @ injLs) + }; + } + | InjR(_) => + if (List.exists( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + ) + ) { + | (injRs, []) => + let unwrap = List.map(Constraint.unwrapR, injRs); + is_inconsistent(~may, unwrap); + | (injRs, other) => is_inconsistent(~may, other @ injRs) + }; + } + | Int(_) + | NotInt(_) => + switch ( + List.partition( + fun + | Constraint.Int(_) + | NotInt(_) => true + | _ => false, + xis, + ) + ) { + | (ns, []) => is_inconsistent_nums(ns) + | (ns, other) => is_inconsistent(~may, other @ ns) + } + | Float(_) + | NotFloat(_) => + switch ( + List.partition( + fun + | Constraint.Float(_) + | NotFloat(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_float(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + | String(_) + | NotString(_) => + switch ( + List.partition( + fun + | Constraint.String(_) + | NotString(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_string(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + /* + * Thoughts for porting the Pair judgment to list: + * Two list constraints are automatically inconsistent if they have different length. + * So we first find maximum and minimum list lengths, and determine if they are the same. + * If so, we rearrange them in item-first order, and check each of them. + */ + | List(_) => + switch ( + List.partition( + fun + | Constraint.List(_) => true + | _ => false, + xis, + ) + ) { + | (lists, []) => + let lengths = + List.map(x => List.length(Constraint.unwrap_list(x)), lists); + // check if all lengths are equal + // This could be done with exceptions, but I found nothing related on ReasonML website. + let all_lengths_are_equal = + List.for_all(x => x == List.hd(lengths), List.tl(lengths)); + if (all_lengths_are_equal) { + let order_by_index = + List.fold_left( + // ordered_by_index: list(list(t)); item: packed version of list(t) + (ordered_by_index, lst) => + List.map2( + // We need a function that maps `(list(t), t)` to list(list(t) + (old_list, item) => [item, ...old_list], + ordered_by_index, + Constraint.unwrap_list(lst), + ), + // Initial version of empty list, in list(list(t)) + List.map(x => [x], Constraint.unwrap_list(List.hd(lists))), + // Rest of items + List.tl(lists), + ); + // Check if there are inconsistency in each element + List.fold_left( + (previous, item) => previous || is_inconsistent(~may, item), + may, + order_by_index, + ); + } else { + true; // Automatically inconsistent + }; + | (lists, other) => is_inconsistent(~may, other @ lists) + } + } }; -let rec is_indet = (e: DHExp.t): bool => - switch (e) { - | EmptyHole(_, _) => true - | NonEmptyHole(_, _, _, e) => is_final(e) - | _ => false - } -and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); +let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => + is_inconsistent( + ~may=false, + Constraint.[And(truify(xi_cur), dual(falsify(xi_pre)))], + ); + +let is_exhaustive = (xi: Constraint.t): bool => + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file diff --git a/src/haz3lcore/dynamics/Sets.re b/src/haz3lcore/dynamics/Sets.re new file mode 100644 index 0000000000..67b6099709 --- /dev/null +++ b/src/haz3lcore/dynamics/Sets.re @@ -0,0 +1,23 @@ +module IntSet = + Set.Make({ + type t = int; + let compare = compare; + }); + +module BoolSet = + Set.Make({ + type t = bool; + let compare = compare; + }); + +module FloatSet = + Set.Make({ + type t = float; + let compare = compare; + }); + +module StringSet = + Set.Make({ + type t = float; + let compare = compare; + }); From d9ff68106ee0ec8e28132141b471e62e23d0102f Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 23 Aug 2023 20:13:11 +0800 Subject: [PATCH 046/229] Fixed dependency problem. --- opam.export | 96 +++++++++++++++++---------------- src/haz3lcore/dynamics/Incon.re | 2 +- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/opam.export b/opam.export index 98f8552d3a..9cf1612dd5 100644 --- a/opam.export +++ b/opam.export @@ -2,20 +2,20 @@ opam-version: "2.0" compiler: ["ocaml-base-compiler.5.0.0"] roots: [ "incr_dom.v0.15.1" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" - "merlin.4.8-500" + "merlin.4.9-500" "ocaml-base-compiler.5.0.0" - "ocaml-lsp-server.1.15.1-5.0" - "ocamlformat.0.25.1" - "omd.1.3.2" + "ocaml-lsp-server.1.16.2" + "ocamlformat.0.26.0" + "omd.2.0.0~alpha4" "ppx_deriving.5.2.1" "ppx_yojson_conv.v0.15.1" "ptmap.2.0.5" - "reason.3.8.2" - "tezt.3.0.0" + "reason.3.9.0" + "tezt.3.1.1" "unionFind.20220122" - "utop.2.11.0" + "utop.2.13.1" ] installed: [ "abstract_algebra.v0.15.0" @@ -36,24 +36,26 @@ installed: [ "bigstringaf.0.9.1" "bin_prot.v0.15.0" "camlp-streams.5.0.1" - "chrome-trace.3.7.0" - "cmdliner.1.1.1" + "chrome-trace.3.10.0" + "cmdliner.1.2.0" + "conf-autoconf.0.1" + "conf-which.1" "core.v0.15.1" "core_kernel.v0.15.0" "cppo.1.6.9" - "csexp.1.5.1" + "csexp.1.5.2" "cstruct.6.2.0" - "dot-merlin-reader.4.6" - "dune.3.7.0" - "dune-build-info.3.7.0" - "dune-configurator.3.7.0" - "dune-rpc.3.6.2" - "dyn.3.6.2" + "dot-merlin-reader.4.9" + "dune.3.10.0" + "dune-build-info.3.10.0" + "dune-configurator.3.10.0" + "dune-rpc.3.10.0" + "dyn.3.10.0" "either.1.0.0" "ezjsonm.1.3.0" - "fiber.3.6.2" + "fiber.3.7.0" "fieldslib.v0.15.0" - "fix.20220121" + "fix.20230505" "fmt.0.9.0" "fpath.0.7.3" "gen.1.1" @@ -65,24 +67,24 @@ installed: [ "incremental.v0.15.0" "int_repr.v0.15.0" "jane-street-headers.v0.15.0" - "js_of_ocaml.4.1.0" - "js_of_ocaml-compiler.4.1.0" - "js_of_ocaml-ppx.4.1.0" + "js_of_ocaml.5.4.0" + "js_of_ocaml-compiler.5.4.0" + "js_of_ocaml-ppx.5.4.0" "jsonm.1.0.2" "jst-config.v0.15.1" - "lambda-term.3.3.1" + "lambda-term.3.3.2" "lambdasoup.1.0.0" "logs.0.7.0" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" "lwt_react.1.2.0" "markup.1.0.3" - "menhir.20220210" - "menhirLib.20220210" - "menhirSdk.20220210" - "merlin.4.8-500" + "menhir.20230608" + "menhirLib.20230608" + "menhirSdk.20230608" + "merlin.4.9-500" "merlin-extend.0.6.1" - "merlin-lib.4.8-500" + "merlin-lib.4.9-500" "mew.0.1.0" "mew_vi.0.5.0" "num.1.4" @@ -90,28 +92,28 @@ installed: [ "ocaml-base-compiler.5.0.0" "ocaml-compiler-libs.v0.12.4" "ocaml-config.3" - "ocaml-lsp-server.1.15.1-5.0" + "ocaml-lsp-server.1.16.2" "ocaml-options-vanilla.1" "ocaml-syntax-shims.1.0.0" "ocaml-version.3.6.1" "ocamlbuild.0.14.2" - "ocamlc-loc.3.6.2" + "ocamlc-loc.3.10.0" "ocamlfind.1.9.6" - "ocamlformat.0.25.1" - "ocamlformat-lib.0.25.1" - "ocamlformat-rpc-lib.0.25.1" + "ocamlformat.0.26.0" + "ocamlformat-lib.0.26.0" + "ocamlformat-rpc-lib.0.26.0" "ocp-indent.1.8.1" "ocplib-endian.1.2" "octavius.1.2.2" "odoc-parser.2.0.0" "ojs.1.1.2" - "omd.1.3.2" - "ordering.3.6.2" + "omd.2.0.0~alpha4" + "ordering.3.10.0" "parsexp.v0.15.0" "pp.1.1.2" "ppx_assert.v0.15.0" "ppx_base.v0.15.0" - "ppx_bench.v0.15.0" + "ppx_bench.v0.15.1" "ppx_bin_prot.v0.15.0" "ppx_cold.v0.15.0" "ppx_compare.v0.15.0" @@ -126,7 +128,7 @@ installed: [ "ppx_hash.v0.15.0" "ppx_here.v0.15.0" "ppx_ignore_instrumentation.v0.15.0" - "ppx_inline_test.v0.15.0" + "ppx_inline_test.v0.15.1" "ppx_jane.v0.15.0" "ppx_js_style.v0.15.0" "ppx_let.v0.15.0" @@ -145,14 +147,14 @@ installed: [ "ppx_variants_conv.v0.15.0" "ppx_yojson_conv.v0.15.1" "ppx_yojson_conv_lib.v0.15.0" - "ppxlib.0.28.0" + "ppxlib.0.30.0" "protocol_version_header.v0.15.0" "ptmap.2.0.5" "re.1.10.4" "react.1.2.2" - "reason.3.8.2" + "reason.3.9.0" "result.1.5" - "sedlex.3.1" + "sedlex.3.2" "seq.base" "sexplib.v0.15.1" "sexplib0.v0.15.1" @@ -161,9 +163,9 @@ installed: [ "stdcompat.19" "stdio.v0.15.0" "stdlib-shims.0.3.0" - "stdune.3.6.2" + "stdune.3.10.0" "stringext.1.6.0" - "tezt.3.0.0" + "tezt.3.1.1" "time_now.v0.15.0" "topkg.1.0.7" "trie.1.0.0" @@ -173,16 +175,16 @@ installed: [ "unionFind.20220122" "uri.4.2.0" "uri-sexp.4.2.0" - "utop.2.11.0" + "utop.2.13.1" "uucp.15.0.0" "uunf.15.0.0" "uuseg.15.0.0" "uutf.1.0.3" "variantslib.v0.15.0" "virtual_dom.v0.15.1" - "xdg.3.7.0" - "yojson.2.0.2" - "zed.3.2.1" + "xdg.3.10.0" + "yojson.2.1.0" + "zed.3.2.3" ] pinned: [ "async_js.v0.15.1" diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 204d181cb6..8b9bd7b02d 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -243,4 +243,4 @@ let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => ); let is_exhaustive = (xi: Constraint.t): bool => - is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); From bfc1fae1201731938a3f9e881eb0c1a4918d98a9 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 27 Aug 2023 09:54:46 -0400 Subject: [PATCH 047/229] Fixed a bug related to incomplete rebasing. --- src/haz3lcore/dynamics/Constraint.re | 5 +---- src/haz3lcore/dynamics/InvalidOperationError.re | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 1388e2fde6..0a4b705a2d 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -19,10 +19,7 @@ type t = // How to replace this function? let rec constrains = (c: t, ty: Typ.t): bool => - switch ( - c, - Typ.weak_head_normalize(Builtins.ctx(Builtins.Pervasives.builtins), ty), - ) { + switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { | (Truth, _) | (Falsity, _) | (Hole, _) => true diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index 858e7b0757..3a6e31c35f 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -5,8 +5,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel - | InvalidIntOfString - | InvalidFloatOfString + // | InvalidIntOfString + // | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -16,7 +16,7 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" - | InvalidIntOfString => "Error: Invalid String to Int Conversion" - | InvalidFloatOfString => "Error: Invalid String to Float Conversion" + // | InvalidIntOfString => "Error: Invalid String to Int Conversion" + // | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; From 93477bdcd6e2ff014854614501f2e12572775a46 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 28 Aug 2023 14:48:41 -0400 Subject: [PATCH 048/229] Add a comment to justify not needing capture avoidance in evaluator. --- src/haz3lcore/dynamics/Evaluator.re | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Evaluator.re b/src/haz3lcore/dynamics/Evaluator.re index c7fcf624bb..e059b15965 100644 --- a/src/haz3lcore/dynamics/Evaluator.re +++ b/src/haz3lcore/dynamics/Evaluator.re @@ -647,7 +647,9 @@ let rec ty_subst = | TypFun(utpat, body) => switch (Term.UTPat.tyvar_of_utpat(utpat)) { | Some(x') when x == x' => exp - | _ => TypFun(utpat, re(body)) + | _ => + /* Note that we do not have to worry about capture avoidance, since s will always be closed. */ + TypFun(utpat, re(body)) } | NonEmptyHole(errstat, mv, hid, t) => NonEmptyHole(errstat, mv, hid, re(t)) From d2f43352dd6f9dadad0fd541d484c001c5da7a10 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Mon, 28 Aug 2023 15:14:03 -0400 Subject: [PATCH 049/229] Banned supporting a tuple pattern that itself has an annotation on it --- src/haz3lcore/statics/Statics.re | 1 - 1 file changed, 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index a925277ea3..dc06991589 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -52,7 +52,6 @@ let is_recursive = (ctx, p, def, syn: Typ.t) => { | (Some(num_vars), Some(num_fns)) when num_vars != 0 && num_vars == num_fns => switch (Typ.normalize(ctx, syn)) { - | Unknown(_) => true | Arrow(_) when num_vars == 1 => true | Prod(syns) when List.length(syns) == num_vars => syns From 19610562510b8308494aeb48a8433a7dd5f2bbaf Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Mon, 28 Aug 2023 15:19:05 -0400 Subject: [PATCH 050/229] Update Statics.re --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index dc06991589..398dfd45e1 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -52,7 +52,7 @@ let is_recursive = (ctx, p, def, syn: Typ.t) => { | (Some(num_vars), Some(num_fns)) when num_vars != 0 && num_vars == num_fns => switch (Typ.normalize(ctx, syn)) { - | Arrow(_) when num_vars == 1 => true + | Arrow(_) => num_vars == 1 | Prod(syns) when List.length(syns) == num_vars => syns |> List.for_all( @@ -279,12 +279,12 @@ and uexp_to_info_map = go_pat(~is_synswitch=false, ~mode=Ana(def.ty), p, m); (def, p_ana, m); } else { - let p_syn_ty = p_syn.ty; - let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn_ty), def, m) /* Analyze pattern to incorporate def type into ctx */; + let (def_base, _m) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m) /* Analyze pattern to incorporate def type into ctx */; let (p_ana, m) = go_pat(~is_synswitch=false, ~mode=Ana(def_base.ty), p, m); let def_ctx = p_ana.ctx; - let (def_base2, m) = go'(~ctx=def_ctx, ~mode=Ana(p_syn_ty), def, m); + let (def_base2, _m) = + go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { ty_p == Typ.Unknown(SynSwitch) && !Typ.eq(ty_fn1, ty_fn2) ? ty_fn1 : Unknown(SynSwitch); From d6d8c177382d2d0e00b61f886a3672b213dbe718 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 02:46:48 -0400 Subject: [PATCH 051/229] Add parentheses to left type of functions when necessary. Lowercase forall and rec. --- src/haz3lweb/view/Type.re | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index e3afd602bb..ed08e6099e 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -17,8 +17,24 @@ let prov_view: Typ.type_provenance => Node.t = | TypeHole => div(~attr=clss(["typ-mod", "type-hole"]), [text("𝜏")]) | SynSwitch => div(~attr=clss(["typ-mod", "syn-switch"]), [text("⇒")]); +/* Does the type require parentheses when on the left of an arrow? */ +let needs_parens = (ty: Haz3lcore.Typ.t): bool => + switch (ty) { + | Unknown(_) + | Int + | Float + | String + | Bool + | Var(_) => false + | Rec(_, _) + | Forall(_, _) => true + | List(_) => false /* is already wrapped in [] */ + | Arrow(_, _) => true + | Prod(_) + | Sum(_) => true /* disambiguate between (A + B) -> C and A + (B -> C) */ + }; + let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => - //TODO: parens on ops when ambiguous switch (ty) { | Unknown(prov) => div( @@ -37,12 +53,12 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Rec(name, t) => div( ~attr=clss(["typ-view", "Rec"]), - [text("Rec " ++ name ++ ". "), view_ty(t)], + [text("rec " ++ name ++ ". "), view_ty(t)], ) | Forall(name, t) => div( ~attr=clss(["typ-view", "Forall"]), - [text("Forall " ++ name ++ ". "), view_ty(t)], + [text("forall " ++ name ++ ". "), view_ty(t)], ) | List(t) => div( @@ -52,7 +68,7 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Arrow(t1, t2) => div( ~attr=clss(["typ-view", "Arrow"]), - [view_ty(t1), text(" -> "), view_ty(t2)], + paren_view(t1) @ [text(" -> "), view_ty(t2)], ) | Prod([]) => div(~attr=clss(["typ-view", "Prod"]), [text("()")]) | Prod([_]) => @@ -64,8 +80,11 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => text("("), div( ~attr=clss(["typ-view", "Prod"]), - [view_ty(t0)] - @ (List.map(t => [text(", "), view_ty(t)], ts) |> List.flatten), + paren_view(t0) + @ ( + List.map(t => [text(", "), ...paren_view(t)], ts) + |> List.flatten + ), ), text(")"), ], @@ -87,6 +106,12 @@ and ctr_view = ((ctr, typ)) => switch (typ) { | None => [text(ctr)] | Some(typ) => [text(ctr ++ "("), view_ty(typ), text(")")] + } +and paren_view = typ => + if (needs_parens(typ)) { + [text("("), view_ty(typ), text(")")]; + } else { + [view_ty(typ)]; }; let view = (ty: Haz3lcore.Typ.t): Node.t => From ca727f2eb9dcab6835c62ea09231e70b879b8228 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 03:04:23 -0400 Subject: [PATCH 052/229] Disallow shadowing with type variables. --- src/haz3lcore/statics/Info.re | 4 +--- src/haz3lcore/statics/Statics.re | 10 ++++++++-- src/haz3lcore/statics/TypBase.re | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index ea96f63bc8..3e67eb31be 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -389,9 +389,7 @@ let status_typ = let status_tpat = (ctx: Ctx.t, utpat: UTPat.t): status_tpat => switch (utpat.term) { | EmptyHole => NotInHole(Empty) - | Var(name) - when Form.is_base_typ(name) || Ctx.lookup_alias(ctx, name) != None => - InHole(ShadowsType(name)) + | Var(name) when Ctx.shadows_typ(ctx, name) => InHole(ShadowsType(name)) | Var(name) => NotInHole(Var(name)) | Invalid(_) => InHole(NotAVar(NotCapitalized)) | MultiHole(_) => InHole(NotAVar(Other)) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2f5ef952a8..ed437719c0 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -251,7 +251,8 @@ and uexp_to_info_map = ~co_ctx=CoCtx.mk(ctx, p.ctx, e.co_ctx), m, ); - | TypFun({term: Var(name), _} as utpat, body) => + | TypFun({term: Var(name), _} as utpat, body) + when !Ctx.shadows_typ(ctx, name) => let mode_body = Mode.of_forall(Some(name), mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; let ctx_body = @@ -261,12 +262,17 @@ and uexp_to_info_map = ); let (body, m) = go'(~ctx=ctx_body, ~mode=mode_body, body, m); add(~self=Just(Forall(name, body.ty)), ~co_ctx=body.co_ctx, m); + | TypFun({term: Var(name), _} as utpat, body) + when Ctx.shadows_typ(ctx, name) => + let ({co_ctx, ty: ty_body, _}: Info.exp, m) = go'(~ctx, ~mode, body, m); + let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; + add(~self=Just(Forall(name, ty_body)), ~co_ctx, m); | TypFun(utpat, body) => let mode_body = Mode.of_forall(None, mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; let (body, m) = go(~mode=mode_body, body, m); add( - ~self=Just(Forall("expected_type_variable", body.ty)), + ~self=Just(Forall("?", body.ty)), ~co_ctx=body.co_ctx, m, ); diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index b089ee0fc4..fd8fe821a9 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -648,7 +648,7 @@ and Ctx: { |> (((ctx, _, _)) => List.rev(ctx)); let shadows_typ = (ctx: t, name: TypVar.t): bool => - Form.is_base_typ(name) || lookup_alias(ctx, name) != None; + Form.is_base_typ(name) || is_alias(ctx, name) || is_tvar(ctx, name); } and Kind: { [@deriving (show({with_path: false}), sexp, yojson)] From a140fa6adc3796fc188f983d45eeb8f9f42289b7 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 03:16:50 -0400 Subject: [PATCH 053/229] Add disallowing of shadowing for type variables. --- src/haz3lcore/statics/Info.re | 19 +++++++++++++++++-- src/haz3lcore/statics/Statics.re | 6 +----- src/haz3lweb/view/CursorInspector.re | 9 +++++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 3e67eb31be..46e8e9591f 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -160,10 +160,17 @@ type type_var_err = | Other | NotCapitalized; +/* What are we shadowing? */ +[@deriving (show({with_path: false}), sexp, yojson)] +type shadow_src = + | BaseTyp + | TyAlias + | TyVar; + /* Type pattern term errors */ [@deriving (show({with_path: false}), sexp, yojson)] type error_tpat = - | ShadowsType(TypVar.t) + | ShadowsType(TypVar.t, shadow_src) | NotAVar(type_var_err); /* Type pattern ok statuses for cursor inspector */ @@ -389,7 +396,15 @@ let status_typ = let status_tpat = (ctx: Ctx.t, utpat: UTPat.t): status_tpat => switch (utpat.term) { | EmptyHole => NotInHole(Empty) - | Var(name) when Ctx.shadows_typ(ctx, name) => InHole(ShadowsType(name)) + | Var(name) when Ctx.shadows_typ(ctx, name) => + let f = src => InHole(ShadowsType(name, src)); + if (Form.is_base_typ(name)) { + f(BaseTyp); + } else if (Ctx.is_alias(ctx, name)) { + f(TyAlias); + } else { + f(TyVar); + }; | Var(name) => NotInHole(Var(name)) | Invalid(_) => InHole(NotAVar(NotCapitalized)) | MultiHole(_) => InHole(NotAVar(Other)) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ed437719c0..e16242db47 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -271,11 +271,7 @@ and uexp_to_info_map = let mode_body = Mode.of_forall(None, mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; let (body, m) = go(~mode=mode_body, body, m); - add( - ~self=Just(Forall("?", body.ty)), - ~co_ctx=body.co_ctx, - m, - ); + add(~self=Just(Forall("?", body.ty)), ~co_ctx=body.co_ctx, m); | Let(p, def, body) => let (p_syn, _m) = go_pat(~is_synswitch=true, ~mode=Syn, p, m); let def_ctx = extend_let_def_ctx(ctx, p, p_syn.ctx, def); diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 1419aa81c1..dc027a8277 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -192,10 +192,15 @@ let tpat_view = (_: Term.Cls.t, status: Info.status_tpat) => | InHole(NotAVar(NotCapitalized)) => div_err([text("Must begin with a capital letter")]) | InHole(NotAVar(_)) => div_err([text("Expected an alias")]) - | InHole(ShadowsType(name)) when Form.is_base_typ(name) => + | InHole(ShadowsType(name, BaseTyp)) => div_err([text("Can't shadow base type"), Type.view(Var(name))]) - | InHole(ShadowsType(name)) => + | InHole(ShadowsType(name, TyAlias)) => div_err([text("Can't shadow existing alias"), Type.view(Var(name))]) + | InHole(ShadowsType(name, TyVar)) => + div_err([ + text("Can't shadow existing type variable"), + Type.view(Var(name)), + ]) }; let view_of_info = From 256a8fcedbd5e89390f8fefad93aadc8d16154b8 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 03:58:52 -0400 Subject: [PATCH 054/229] Use . (as opposed to ->) to delineate forall/rec binding from body. --- src/haz3lcore/lang/Form.re | 4 ++-- src/haz3lcore/statics/MakeTerm.re | 4 ++-- src/haz3lcore/statics/Term.re | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index 03b092232c..522579d47f 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -256,8 +256,8 @@ let forms: list((string, t)) = [ ("parens_typ", mk(ii, ["(", ")"], mk_op(Typ, [Typ]))), ("fun_", mk(ds, ["fun", "->"], mk_pre(P.fun_, Exp, [Pat]))), ("typfun", mk(ds, ["typfun", "->"], mk_pre(P.fun_, Exp, [TPat]))), - ("forall", mk(ds, ["forall", "->"], mk_pre(P.fun_, Typ, [TPat]))), - ("rec", mk(ds, ["rec", "->"], mk_pre(P.fun_, Typ, [TPat]))), + ("forall", mk(ds, ["forall", "."], mk_pre(P.fun_, Typ, [TPat]))), + ("rec", mk(ds, ["rec", "."], mk_pre(P.fun_, Typ, [TPat]))), ("if_", mk(ds, ["if", "then", "else"], mk_pre(P.if_, Exp, [Exp, Exp]))), ("ap_exp", mk(ii, ["(", ")"], mk_post(P.ap, Exp, [Exp]))), ("ap_pat", mk(ii, ["(", ")"], mk_post(P.ap, Pat, [Pat]))), diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 68d4c88cc3..56277f9940 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -404,8 +404,8 @@ and typ_term: unsorted => (UTyp.term, list(Id.t)) = { | ([(_id, x)], []) => ret( switch (x) { - | (["forall", "->"], [TPat(tpat)]) => Forall(tpat, t) - | (["rec", "->"], [TPat(tpat)]) => Rec(tpat, t) + | (["forall", "."], [TPat(tpat)]) => Forall(tpat, t) + | (["rec", "."], [TPat(tpat)]) => Rec(tpat, t) | _ => hole(tm) }, ) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index c0418f8be3..660ed07bfc 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -49,10 +49,10 @@ module UTPat = { let show_cls: cls => string = fun - | Invalid => "Invalid type alias" - | MultiHole => "Broken type alias" - | EmptyHole => "Empty type alias hole" - | Var => "Type alias"; + | Invalid => "Invalid type variable name" + | MultiHole => "Broken type name" + | EmptyHole => "Empty type variable hole" + | Var => "Type variable"; let tyvar_of_utpat = ({ids: _, term}) => switch (term) { From 9c4403d7a1677f5692d77a3aedf34a74718bcadd Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 04:24:17 -0400 Subject: [PATCH 055/229] Make forall/rec bind tighter than sum to fix parsing bug. --- src/haz3lcore/statics/MakeTerm.re | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 56277f9940..badafed0ba 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -392,6 +392,13 @@ and typ_term: unsorted => (UTyp.term, list(Id.t)) = { | ([(_, (["(", ")"], [Typ(typ)]))], []) => ret(Ap(t, typ)) | _ => ret(hole(tm)) } + /* forall and rec have to be before sum so that they bind tighter. + * Thus `rec A . Left(A) + Right(B)` get parsed as `rec A . (Left(A) + Right(B))` + * If this is below the case for sum, then it gets parsed as an invalid form. */ + | Pre(([(_id, (["forall", "."], [TPat(tpat)]))], []), Typ(t)) => + ret(Forall(tpat, t)) + | Pre(([(_id, (["rec", "."], [TPat(tpat)]))], []), Typ(t)) => + ret(Rec(tpat, t)) | Pre(tiles, Typ({term: Sum(t0), ids})) as tm => /* Case for leading prefix + preceeding a sum */ switch (tiles) { @@ -401,14 +408,6 @@ and typ_term: unsorted => (UTyp.term, list(Id.t)) = { | Pre(tiles, Typ(t)) as tm => switch (tiles) { | ([(_, (["+"], []))], []) => ret(Sum([parse_sum_term(t)])) - | ([(_id, x)], []) => - ret( - switch (x) { - | (["forall", "."], [TPat(tpat)]) => Forall(tpat, t) - | (["rec", "."], [TPat(tpat)]) => Rec(tpat, t) - | _ => hole(tm) - }, - ) | _ => ret(hole(tm)) } | Bin(Typ(t1), tiles, Typ(t2)) as tm when is_typ_bsum(tiles) != None => From cb8191175807bc7c7f4d378ae6a786aef5a83d78 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 14:05:46 -0400 Subject: [PATCH 056/229] Change display information to "type binding" instead of alias or variable. --- src/haz3lcore/statics/Term.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 660ed07bfc..90f1d1a7f6 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -49,10 +49,10 @@ module UTPat = { let show_cls: cls => string = fun - | Invalid => "Invalid type variable name" - | MultiHole => "Broken type name" - | EmptyHole => "Empty type variable hole" - | Var => "Type variable"; + | Invalid => "Invalid type binding name" + | MultiHole => "Broken type binding" + | EmptyHole => "Empty type binding hole" + | Var => "Type binding"; let tyvar_of_utpat = ({ids: _, term}) => switch (term) { From 4e4b1cfe55df83feb71172979b4f3ea0a0d753ee Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 14:07:31 -0400 Subject: [PATCH 057/229] Make shadowing typfun use the same case as a hole in tvar name. --- src/haz3lcore/statics/Statics.re | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index e16242db47..4221ca4a34 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -262,11 +262,6 @@ and uexp_to_info_map = ); let (body, m) = go'(~ctx=ctx_body, ~mode=mode_body, body, m); add(~self=Just(Forall(name, body.ty)), ~co_ctx=body.co_ctx, m); - | TypFun({term: Var(name), _} as utpat, body) - when Ctx.shadows_typ(ctx, name) => - let ({co_ctx, ty: ty_body, _}: Info.exp, m) = go'(~ctx, ~mode, body, m); - let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; - add(~self=Just(Forall(name, ty_body)), ~co_ctx, m); | TypFun(utpat, body) => let mode_body = Mode.of_forall(None, mode); let m = utpat_to_info_map(~ctx, ~ancestors, utpat, m) |> snd; From 3f95648bd637dd8fa3b16647f2606b51c49d2901 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 14:53:55 -0400 Subject: [PATCH 058/229] Add () around tuple output. --- src/haz3lweb/view/dhcode/layout/DHDoc_common.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re index 8b8ec43794..66aa66e5d7 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re @@ -134,7 +134,7 @@ let mk_comma_seq = (ld, rd, l) => { let mk_ListLit = l => mk_comma_seq("[", "]", l); -let mk_Tuple = elts => mk_comma_seq("", "", elts); +let mk_Tuple = elts => mk_comma_seq("(", ")", elts); let mk_Ap = (doc1, doc2) => Doc.(hcats([doc1, text("("), doc2, text(")")])); From 1fe28e25dd09a6e5996912016d7d1b82f855a838 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 15:07:31 -0400 Subject: [PATCH 059/229] Add Example scratchpad for polymorphism and recursive types. --- src/haz3lweb/Init.ml | 1275 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1275 insertions(+) diff --git a/src/haz3lweb/Init.ml b/src/haz3lweb/Init.ml index 0306751d59..be135988a7 100644 --- a/src/haz3lweb/Init.ml +++ b/src/haz3lweb/Init.ml @@ -9300,6 +9300,1281 @@ let startup : PersistentData.t = let Yo(1): +Yo(Bool) = Yo(true) in #err: type incons#\n\ \"Thats all, folks\"\n"; } ) ); + ( "Polymorphism", + ( 4819, + { + zipper = + "((selection((focus \ + Left)(content())))(backpack())(relatives((siblings(((Tile((id \ + 4778)(label(ex1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4779)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4781)(content(Whitespace\" \"))))(Tile((id \ + 4788)(label(ex2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4789)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4791)(content(Whitespace\" \")))))((Tile((id \ + 4794)(label(ex3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4795)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4797)(content(Whitespace\" \"))))(Tile((id \ + 4800)(label(ex4))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 4801)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4803)(content(Whitespace\" \"))))(Tile((id \ + 4806)(label(ex5))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))(ancestors((((id \ + 4808)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards((0)(1)))(children(()())))(((Secondary((id \ + 1497)(content(Comment\"# Polymorphism #\"))))(Secondary((id \ + 1465)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1544)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1675)(content(Comment\"# We can take types as parameters to \ + type functions, #\"))))(Secondary((id \ + 1676)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1722)(content(Comment\"# and use them in annoatations in \ + the body: #\"))))(Secondary((id \ + 1466)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1502)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1503)(content(Whitespace\" \"))))(Tile((id \ + 1506)(label(id))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1507)(content(Whitespace\" \")))))((Secondary((id \ + 1508)(content(Whitespace\" \"))))(Tile((id \ + 1516)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1517)(content(Whitespace\" \ + \"))))(Tile((id 1518)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1520)(content(Whitespace\" \")))))))))(Secondary((id \ + 1522)(content(Whitespace\" \"))))(Tile((id 1527)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1528)(content(Whitespace\" \ + \"))))(Tile((id 1529)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1531)(content(Whitespace\" \"))))(Tile((id \ + 1532)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1533)(content(Whitespace\" \"))))(Tile((id \ + 1534)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1536)(content(Whitespace\" \")))))))))(Secondary((id \ + 1538)(content(Whitespace\" \"))))(Tile((id \ + 1539)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1543)(content(Whitespace\" \")))))))))(Secondary((id \ + 1467)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1723)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1761)(content(Comment\"# Such functions are applied like \ + so: #\"))))(Secondary((id \ + 1468)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4680)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4681)(content(Whitespace\" \"))))(Tile((id \ + 4686)(label(ex1))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4688)(content(Whitespace\" \")))))((Secondary((id \ + 4689)(content(Whitespace\" \"))))(Tile((id \ + 4685)(label(id))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 1766)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 1770)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2088)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2090)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4694)(content(Whitespace\" \")))))))))(Secondary((id \ + 2023)(content(Whitespace\" \"))))(Secondary((id \ + 2085)(content(Comment\"# 1 #\"))))(Secondary((id \ + 1469)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1470)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1878)(content(Comment\"# We can annotate the type of a type \ + function with a forall. #\"))))(Secondary((id \ + 4690)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1884)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1885)(content(Whitespace\" \"))))(Tile((id \ + 1891)(label(const))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1892)(content(Whitespace\" \"))))(Tile((id \ + 1893)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1894)(content(Whitespace\" \"))))(Tile((id \ + 1902)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 1903)(content(Whitespace\" \ + \"))))(Tile((id 1904)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1914)(content(Whitespace\" \")))))))))(Secondary((id \ + 1915)(content(Whitespace\" \"))))(Tile((id \ + 1929)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 1930)(content(Whitespace\" \ + \"))))(Tile((id 1931)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1933)(content(Whitespace\" \")))))))))(Secondary((id \ + 1934)(content(Whitespace\" \"))))(Tile((id \ + 1935)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1937)(content(Whitespace\" \"))))(Tile((id \ + 1939)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1940)(content(Whitespace\" \"))))(Tile((id \ + 1941)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1943)(content(Whitespace\" \"))))(Tile((id \ + 1945)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1946)(content(Whitespace\" \"))))(Tile((id \ + 1947)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1948)(content(Whitespace\" \")))))((Secondary((id \ + 1953)(content(Whitespace\" \"))))(Secondary((id \ + 2008)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1985)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1986)(content(Whitespace\" \ + \"))))(Tile((id 1989)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1991)(content(Whitespace\" \")))))))))(Secondary((id \ + 1993)(content(Whitespace\" \"))))(Tile((id \ + 2001)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2002)(content(Whitespace\" \ + \"))))(Tile((id 2003)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2005)(content(Whitespace\" \")))))))))(Secondary((id \ + 2007)(content(Whitespace\" \"))))(Tile((id 1957)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1958)(content(Whitespace\" \ + \"))))(Tile((id 1960)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1961)(content(Whitespace\" \")))))))))(Secondary((id \ + 1964)(content(Whitespace\" \"))))(Tile((id 1968)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 1969)(content(Whitespace\" \ + \"))))(Tile((id 1971)(label(y))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 1972)(content(Whitespace\" \")))))))))(Secondary((id \ + 1975)(content(Whitespace\" \"))))(Tile((id \ + 1976)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 1977)(content(Whitespace\" \")))))))))(Secondary((id \ + 1879)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4700)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4701)(content(Whitespace\" \"))))(Tile((id \ + 4706)(label(ex2))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4708)(content(Whitespace\" \")))))((Secondary((id \ + 4709)(content(Whitespace\" \"))))(Tile((id \ + 4705)(label(const))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 2025)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2033)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2049)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2056)(label(String))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2057)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2062)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2064)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2077)(label(\"\\\"Hello World\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4713)(content(Whitespace\" \")))))))))(Secondary((id \ + 2079)(content(Whitespace\" \"))))(Secondary((id \ + 2083)(content(Comment\"# 2 #\"))))(Secondary((id \ + 2009)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2091)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2158)(content(Comment\"# We can go beyond rank 1 \ + polymorphism: #\"))))(Secondary((id \ + 2092)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2164)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2165)(content(Whitespace\" \"))))(Tile((id \ + 2187)(label(apply_both))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2188)(content(Whitespace\" \"))))(Tile((id \ + 2191)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2218)(content(Whitespace\" \"))))(Tile((id \ + 2227)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2228)(content(Whitespace\" \ + \"))))(Tile((id 2229)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2231)(content(Whitespace\" \")))))))))(Secondary((id \ + 2232)(content(Whitespace\" \"))))(Tile((id \ + 2240)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2241)(content(Whitespace\" \ + \"))))(Tile((id 2242)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2244)(content(Whitespace\" \")))))))))(Secondary((id \ + 2245)(content(Whitespace\" \"))))(Tile((id \ + 2274)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2282)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2283)(content(Whitespace\" \ + \"))))(Tile((id 2284)(label(D))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2286)(content(Whitespace\" \")))))))))(Secondary((id \ + 2287)(content(Whitespace\" \"))))(Tile((id \ + 2288)(label(D))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2306)(content(Whitespace\" \"))))(Tile((id \ + 2304)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2316)(content(Whitespace\" \"))))(Tile((id \ + 2317)(label(D))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2324)(content(Whitespace\" \"))))(Tile((id \ + 2321)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2323)(content(Whitespace\" \"))))(Tile((id \ + 2327)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2329)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2330)(content(Whitespace\" \"))))(Tile((id \ + 2331)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2333)(content(Whitespace\" \"))))(Tile((id \ + 2334)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2341)(content(Whitespace\" \"))))(Tile((id \ + 2338)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2345)(content(Whitespace\" \"))))(Tile((id \ + 2346)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2347)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2348)(content(Whitespace\" \"))))(Tile((id \ + 2349)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2351)(content(Whitespace\" \"))))(Tile((id \ + 2352)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2353)(content(Whitespace\" \")))))((Secondary((id \ + 2355)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2377)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2378)(content(Whitespace\" \ + \"))))(Tile((id 2380)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2381)(content(Whitespace\" \")))))))))(Secondary((id \ + 2384)(content(Whitespace\" \"))))(Tile((id \ + 2391)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2392)(content(Whitespace\" \ + \"))))(Tile((id 2394)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2395)(content(Whitespace\" \")))))))))(Secondary((id \ + 2402)(content(Whitespace\" \"))))(Tile((id 2408)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2409)(content(Whitespace\" \ + \"))))(Tile((id 2411)(label(f))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2412)(content(Whitespace\" \")))))))))(Secondary((id \ + 2415)(content(Whitespace\" \"))))(Tile((id 2419)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2420)(content(Whitespace\" \ + \"))))(Tile((id 2422)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 2423)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 2424)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2426)(content(Whitespace\" \"))))(Tile((id \ + 2427)(label(y))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 2428)(content(Whitespace\" \")))))))))(Secondary((id \ + 2431)(content(Whitespace\" \"))))(Tile((id \ + 2432)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2433)(label(f))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 2452)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2453)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2440)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2442)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2443)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2445)(content(Whitespace\" \"))))(Tile((id \ + 2446)(label(f))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 2455)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2456)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2447)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2449)(label(y))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 2450)(content(Whitespace\" \")))))))))(Secondary((id \ + 2308)(content(Whitespace\" \"))))(Secondary((id \ + 2313)(content(Whitespace\" \"))))(Secondary((id \ + 2159)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4719)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4720)(content(Whitespace\" \"))))(Tile((id \ + 4725)(label(ex3))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4727)(content(Whitespace\" \")))))((Secondary((id \ + 4728)(content(Whitespace\" \"))))(Tile((id \ + 4724)(label(apply_both))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 2476)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2481)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2483)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2490)(label(String))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2491)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2494)(label(id))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2495)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2501)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2503)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2504)(content(Whitespace\" \"))))(Tile((id \ + 2517)(label(\"\\\"Hello World\\\"\"))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4732)(content(Whitespace\" \")))))))))(Secondary((id \ + 2526)(content(Whitespace\" \"))))(Secondary((id \ + 2548)(content(Comment\"# (3, \\\"Hello World\\\") \ + #\"))))(Secondary((id 2521)(content(Whitespace\" \ + \"))))(Secondary((id \ + 2457)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2549)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 2650)(content(Comment\"# Finally, here is a more in-depth, \ + yet applicable example: polymorphic map \ + #\"))))(Secondary((id \ + 2550)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2932)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2933)(content(Whitespace\" \"))))(Tile((id \ + 2943)(label(emptylist))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2944)(content(Whitespace\" \"))))(Tile((id \ + 2945)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2946)(content(Whitespace\" \"))))(Tile((id \ + 2954)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2955)(content(Whitespace\" \ + \"))))(Tile((id 2956)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2958)(content(Whitespace\" \")))))))))(Secondary((id \ + 2959)(content(Whitespace\" \"))))(Tile((id 2960)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2961)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2963)(content(Whitespace\" \")))))((Secondary((id \ + 2964)(content(Whitespace\" \"))))(Tile((id \ + 2972)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2973)(content(Whitespace\" \ + \"))))(Tile((id 2974)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2976)(content(Whitespace\" \")))))))))(Secondary((id \ + 2978)(content(Whitespace\" \"))))(Tile((id \ + 2980)(label([]))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2984)(content(Whitespace\" \")))))))))(Secondary((id \ + 2986)(content(Whitespace\" \"))))(Secondary((id \ + 3009)(content(Comment\"# polymorphic constant \ + #\"))))(Secondary((id \ + 2927)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2656)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 2657)(content(Whitespace\" \"))))(Tile((id \ + 2661)(label(map))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2662)(content(Whitespace\" \"))))(Tile((id \ + 2663)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2664)(content(Whitespace\" \"))))(Tile((id \ + 2672)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2673)(content(Whitespace\" \ + \"))))(Tile((id 2674)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2676)(content(Whitespace\" \")))))))))(Secondary((id \ + 2677)(content(Whitespace\" \"))))(Tile((id \ + 2685)(label(forall .))(mold((out \ + Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 2686)(content(Whitespace\" \ + \"))))(Tile((id 2687)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2689)(content(Whitespace\" \")))))))))(Secondary((id \ + 2690)(content(Whitespace\" \"))))(Tile((id \ + 2691)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2692)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2701)(content(Whitespace\" \"))))(Tile((id \ + 2697)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2698)(content(Whitespace\" \"))))(Tile((id \ + 2699)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2702)(content(Whitespace\" \"))))(Tile((id \ + 2704)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2705)(content(Whitespace\" \"))))(Tile((id \ + 2706)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2707)(label([ ]))(mold((out Typ)(in_(Typ))(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2708)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2719)(content(Whitespace\" \"))))(Tile((id \ + 2713)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2714)(content(Whitespace\" \"))))(Tile((id 2715)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2716)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + 2720)(content(Whitespace\" \")))))((Secondary((id \ + 2721)(content(Whitespace\" \"))))(Secondary((id \ + 2722)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2730)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2731)(content(Whitespace\" \ + \"))))(Tile((id 2732)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2734)(content(Whitespace\" \")))))))))(Secondary((id \ + 2736)(content(Whitespace\" \"))))(Tile((id \ + 2744)(label(typfun ->))(mold((out \ + Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2745)(content(Whitespace\" \ + \"))))(Tile((id 2746)(label(B))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 2748)(content(Whitespace\" \")))))))))(Secondary((id \ + 2755)(content(Whitespace\" \"))))(Tile((id 2759)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2760)(content(Whitespace\" \ + \"))))(Tile((id 2762)(label(f))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2763)(content(Whitespace\" \"))))(Tile((id \ + 2764)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2766)(content(Whitespace\" \"))))(Tile((id \ + 2775)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 2776)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2788)(content(Whitespace\" \"))))(Tile((id \ + 2780)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2782)(content(Whitespace\" \"))))(Tile((id \ + 2783)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2784)(content(Whitespace\" \")))))))))(Secondary((id \ + 2787)(content(Whitespace\" \"))))(Tile((id 2792)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2793)(content(Whitespace\" \ + \"))))(Tile((id 2795)(label(l))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2797)(content(Whitespace\" \"))))(Tile((id \ + 2798)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 2800)(content(Whitespace\" \"))))(Tile((id 2801)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 2802)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2803)(content(Whitespace\" \")))))))))(Secondary((id \ + 2807)(content(Whitespace\" \"))))(Secondary((id \ + 4473)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2826)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2827)(content(Whitespace\" \ + \"))))(Tile((id 2829)(label(l))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2838)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2839)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2841)(content(Whitespace\" \ + \"))))(Tile((id 2842)(label(h))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2843)(content(Whitespace\" \"))))(Tile((id \ + 2846)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 6))(sort Pat))((shape(Concave 6))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2847)(content(Whitespace\" \"))))(Tile((id \ + 2848)(label(t))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2849)(content(Whitespace\" \")))))))))(Secondary((id \ + 2852)(content(Whitespace\" \"))))(Tile((id \ + 2863)(label(f))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 2864)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2866)(label(h))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2867)(content(Whitespace\" \"))))(Tile((id \ + 2870)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2871)(content(Whitespace\" \"))))(Tile((id \ + 2874)(label(map))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 2878)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 2879)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2882)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2883)(label(B))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 2884)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2886)(label(f))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 2887)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2889)(label(t))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 2890)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2891)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 2893)(content(Whitespace\" \ + \"))))(Tile((id 2925)(label(_))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 2926)(content(Whitespace\" \")))))))))(Secondary((id \ + 2899)(content(Whitespace\" \"))))(Tile((id \ + 3020)(label(emptylist))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 3023)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 3024)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2836)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 2837)(content(Whitespace\" \")))))))))(Secondary((id \ + 2651)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4740)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4741)(content(Whitespace\" \"))))(Tile((id \ + 4746)(label(ex4))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4748)(content(Whitespace\" \")))))((Secondary((id \ + 4749)(content(Whitespace\" \"))))(Tile((id \ + 4745)(label(map))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id 3033)(label(@< \ + >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 3037)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 3039)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3046)(label(String))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Tile((id \ + 3051)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3068)(label(string_of_int))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Tile((id \ + 3073)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3080)(label([ ]))(mold((out Exp)(in_(Exp))(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Tile((id 3082)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 3086)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3089)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3090)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3092)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 4753)(content(Whitespace\" \")))))))))(Secondary((id \ + 3101)(content(Whitespace\" \"))))(Secondary((id \ + 3125)(content(Comment\"# [\\\"1\\\", \\\"2\\\", \\\"3\\\"] \ + #\"))))(Secondary((id \ + 3126)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3128)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3129)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3147)(content(Comment\"# Recursive types \ + #\"))))(Secondary((id \ + 3148)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3149)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3266)(content(Comment\"# We can express types that are the \ + least fixed point of #\"))))(Secondary((id \ + 3267)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3319)(content(Comment\"# some type function with the rec \ + keyword. #\"))))(Secondary((id \ + 1472)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 681)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 682)(content(Whitespace\" \"))))(Tile((id \ + 970)(label(MyList))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 975)(content(Whitespace\" \")))))((Secondary((id \ + 3332)(content(Whitespace\" \"))))(Tile((id 891)(label(rec \ + .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id 989)(content(Whitespace\" \ + \"))))(Tile((id 4015)(label(A))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children()))))))))(Secondary((id \ + 4013)(content(Whitespace\" \"))))(Tile((id \ + 1075)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 894)(label(Nil))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 851)(content(Whitespace\" \"))))(Tile((id \ + 849)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 852)(content(Whitespace\" \"))))(Tile((id \ + 856)(label(Cons))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 868)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4021)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 873)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 875)(content(Whitespace\" \"))))(Tile((id \ + 4017)(label(A))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + 885)(content(Whitespace\" \")))))))))(Secondary((id \ + 3562)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4217)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4356)(content(Comment\"# Hazel does not (yet) support \ + higher-kinded or existential types, #\"))))(Secondary((id \ + 4287)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4357)(content(Comment\"# So we cannot implement our own \ + polymorphic lists. #\"))))(Secondary((id \ + 4218)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3782)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3899)(content(Comment\"# Now anything that returns an \ + element of the least fixed point matches MyList. \ + #\"))))(Secondary((id \ + 3900)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3905)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3906)(content(Whitespace\" \"))))(Tile((id \ + 3907)(label(x))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 3909)(content(Whitespace\" \"))))(Tile((id \ + 3910)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3911)(content(Whitespace\" \"))))(Tile((id \ + 3918)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3979)(content(Whitespace\" \")))))((Secondary((id \ + 3920)(content(Whitespace\" \"))))(Tile((id \ + 3995)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3926)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3927)(label(1))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3929)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3930)(content(Whitespace\" \"))))(Tile((id \ + 3935)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3936)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3937)(label(2))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3939)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3940)(content(Whitespace\" \"))))(Tile((id \ + 3945)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3946)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 3947)(label(3))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Tile((id \ + 3949)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 14))(sort Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 3950)(content(Whitespace\" \"))))(Tile((id \ + 3954)(label(Nil))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ + 3957)(content(Whitespace\" \")))))))))(Secondary((id \ + 3783)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3563)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4216)(content(Comment\"# Note that if the sum is the top \ + level operator, #\"))))(Secondary((id \ + 3616)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3701)(content(Comment\"# type aliases are implicitly least \ + fixed points on their own name: #\"))))(Secondary((id \ + 990)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1002)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 1011)(content(Whitespace\" \"))))(Tile((id \ + 1091)(label(MyList2))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 1141)(content(Whitespace\" \")))))((Secondary((id \ + 3513)(content(Whitespace\" \"))))(Tile((id \ + 3507)(label(Nil))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3378)(content(Whitespace\" \"))))(Tile((id \ + 3379)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3381)(content(Whitespace\" \"))))(Tile((id \ + 3385)(label(Cons))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3386)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3705)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 3389)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3391)(content(Whitespace\" \"))))(Tile((id \ + 3398)(label(MyList2))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 3399)(content(Whitespace\" \")))))))))(Secondary((id \ + 3706)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 3715)(label(type = in))(mold((out Exp)(in_(TPat \ + Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 3716)(content(Whitespace\" \"))))(Tile((id \ + 4079)(label(Broken))(mold((out TPat)(in_())(nibs(((shape \ + Convex)(sort TPat))((shape Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 3730)(content(Whitespace\" \")))))((Secondary((id \ + 3740)(content(Whitespace\" \"))))(Tile((id \ + 4111)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4122)(content(Whitespace\" \"))))(Tile((id \ + 4121)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 3744)(content(Whitespace\" \"))))(Tile((id \ + 4120)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4134)(label(HasInt))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4135)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4138)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 4062)(content(Whitespace\" \"))))(Tile((id \ + 4063)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 10))(sort Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4065)(content(Whitespace\" \"))))(Tile((id \ + 4149)(label(HasMore))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4098)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4154)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Tile((id \ + 4155)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 14))(sort Typ))((shape(Concave 14))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4156)(content(Whitespace\" \"))))(Tile((id \ + 4153)(label(Broken))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + 4106)(content(Whitespace\" \")))))))))(Secondary((id \ + 3779)(content(Whitespace\" \"))))(Secondary((id \ + 3780)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 3781)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 907)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4566)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4567)(content(Whitespace\" \"))))(Tile((id \ + 4585)(label(list_of_mylist))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 921)(content(Whitespace\" \"))))(Tile((id \ + 4410)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4412)(content(Whitespace\" \"))))(Tile((id \ + 4435)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 4418)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4448)(content(Whitespace\" \"))))(Tile((id \ + 4439)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ + 6))(sort Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4441)(content(Whitespace\" \"))))(Tile((id 4603)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id 4444)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + 4604)(content(Whitespace\" \")))))((Secondary((id \ + 4449)(content(Whitespace\" \"))))(Tile((id 4453)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 4454)(content(Whitespace\" \ + \"))))(Tile((id 4458)(label(myl))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4459)(content(Whitespace\" \"))))(Tile((id \ + 4460)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 11))(sort Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4462)(content(Whitespace\" \"))))(Tile((id \ + 4468)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ + Convex)(sort Typ))((shape Convex)(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 4469)(content(Whitespace\" \")))))))))(Secondary((id \ + 4472)(content(Whitespace\" \"))))(Secondary((id \ + 4479)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4484)(label(case end))(mold((out \ + Exp)(in_(Rul))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 4485)(content(Whitespace\" \ + \"))))(Tile((id 4489)(label(myl))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4490)(content(Whitespace\" \"))))(Secondary((id \ + 4491)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4492)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 4494)(content(Whitespace\" \ + \"))))(Tile((id 4497)(label(Nil))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4498)(content(Whitespace\" \")))))))))(Secondary((id \ + 4506)(content(Whitespace\" \"))))(Tile((id \ + 4508)(label([]))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4509)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4510)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ + Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id 4512)(content(Whitespace\" \ + \"))))(Tile((id 4516)(label(Cons))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 4517)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 4519)(label(h))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 4520)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ + 14))(sort Pat))((shape(Concave 14))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4522)(content(Whitespace\" \"))))(Tile((id \ + 4525)(label(t))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 4526)(content(Whitespace\" \")))))))))(Secondary((id \ + 4529)(content(Whitespace\" \"))))(Tile((id \ + 4530)(label(h))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4531)(content(Whitespace\" \"))))(Tile((id \ + 4534)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ + 6))(sort Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4535)(content(Whitespace\" \"))))(Tile((id \ + 4549)(label(list_of_mylist))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 4550)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4552)(label(t))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4560)(content(Whitespace\" \"))))(Secondary((id \ + 4554)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 4601)(content(Whitespace\" \")))))))))(Secondary((id \ + 4606)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 4759)(label(let = in))(mold((out Exp)(in_(Pat \ + Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ + 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ + 4760)(content(Whitespace\" \"))))(Tile((id \ + 4765)(label(ex5))(mold((out Pat)(in_())(nibs(((shape \ + Convex)(sort Pat))((shape Convex)(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 4767)(content(Whitespace\" \")))))((Secondary((id \ + 4768)(content(Whitespace\" \"))))(Tile((id \ + 4764)(label(list_of_mylist))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 4621)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4623)(label(x))(mold((out Exp)(in_())(nibs(((shape \ + Convex)(sort Exp))((shape Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + 4771)(content(Whitespace\" \")))))))))(Secondary((id \ + 4773)(content(Whitespace\" \"))))(Secondary((id \ + 4640)(content(Comment\"# [1, 2, 3] #\"))))(Secondary((id \ + 4643)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4644)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4645)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 4673)(content(Comment\"# All output from examples: \ + #\"))))(Secondary((id \ + 4674)(content(Whitespace\"\\226\\143\\142\")))))()))))))(caret \ + Outer))"; + backup_text = + "# Polymorphism #\n\n\ + # We can take types as parameters to type functions, #\n\ + # and use them in annoatations in the body: #\n\ + let id = typfun A -> fun x : A -> x in\n\n\ + # Such functions are applied like so: #\n\ + let ex1 = id@(1) in # 1 #\n\n\ + # We can annotate the type of a type function with a \ + forall. #\n\ + let const : forall A . forall B . A -> B -> A = \n\ + typfun A -> typfun B -> fun x -> fun y -> x in\n\ + let ex2 = const@@(2)(\"Hello World\") in # 2 #\n\n\ + # We can go beyond rank 1 polymorphism: #\n\ + let apply_both : forall A . forall B . (forall D . D -> D) \ + -> (A , B) -> (A , B) =\n\ + typfun A -> typfun B -> fun f -> fun (x, y) -> (f@(x), \ + f@(y)) in \n\ + let ex3 = apply_both@@(id)(3, \"Hello World\") \ + in # (3, \"Hello World\") # \n\n\ + # Finally, here is a more in-depth, yet applicable example: \ + polymorphic map #\n\ + let emptylist : forall A . [A] = typfun A -> [] in # \ + polymorphic constant #\n\ + let map : forall A . forall B . (A -> B) -> ([A] -> [B]) = \n\ + typfun A -> typfun B -> fun f : (A -> B) -> fun l : [A] -> \n\ + case l\n\ + | h :: t => f(h) :: map@@(f)(t)\n\ + | _ => emptylist@\n\ + end in\n\ + let ex4 = map@@(string_of_int)([1,2,3]) in # \ + [\"1\", \"2\", \"3\"] #\n\n\n\ + # Recursive types #\n\n\ + # We can express types that are the least fixed point of #\n\ + # some type function with the rec keyword. #\n\ + type MyList = rec A. (Nil + Cons(Int, A)) in\n\n\ + # Hazel does not (yet) support higher-kinded or existential \ + types, #\n\ + # So we cannot implement our own polymorphic lists. #\n\n\ + # Now anything that returns an element of the least fixed \ + point matches MyList. #\n\ + let x : MyList = Cons(1, Cons(2, Cons(3, Nil))) in\n\n\ + # Note that if the sum is the top level operator, #\n\ + # type aliases are implicitly least fixed points on their \ + own name: #\n\ + type MyList2 = Nil + Cons(Int, MyList2) in\n\ + type Broken = Int -> (HasInt(Int) + HasMore(Int, Broken)) \ + in \n\n\n\ + let list_of_mylist : (MyList -> [Int]) = fun myl : MyList -> \n\ + case myl \n\ + | Nil => []\n\ + | Cons(h, t) => h :: list_of_mylist(t) \n\ + end in\n\ + let ex5 = list_of_mylist(x) in # [1, 2, 3] #\n\n\n\ + # All output from examples: #\n\ + (ex1, ex2, ex3, ex4, ex5)"; + } ) ); ( "Basic Reference", ( 13633, { From 3923e390141c71f69aba1bcccc31321851c9068b Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 15:29:52 -0400 Subject: [PATCH 060/229] Correct minor error in is_tvar (should not affect anywhere where it's currently used) --- src/haz3lcore/statics/TypBase.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index fd8fe821a9..6a94ecabbe 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -580,8 +580,8 @@ and Ctx: { let is_tvar = (ctx: t, name: TypVar.t): bool => switch (lookup_tvar(ctx, name)) { - | Some(_) => true - | None => false + | Some({kind: Abstract, _}) => true + | _ => false }; let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => From 084f41441655f60fe8be80298942a1919f3421f4 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 30 Aug 2023 15:41:49 -0400 Subject: [PATCH 061/229] Preserve binding names from synthetic to give more intuitive cursor information. --- src/haz3lcore/statics/Info.re | 4 ++-- src/haz3lcore/statics/TypBase.re | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 46e8e9591f..ec45060d40 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -281,7 +281,7 @@ let rec status_common = | None => InHole(Inconsistent(WithArrow(ty))) } | (Just(syn), Ana(ana)) => - switch (Typ.join_fix(ctx, ana, syn)) { + switch (Typ.join_fix(ctx, syn, ana)) { | None => InHole(Inconsistent(Expectation({syn, ana}))) | Some(join) => NotInHole(Ana(Consistent({ana, syn, join}))) } @@ -299,7 +299,7 @@ let rec status_common = | (IsMulti, _) => NotInHole(Syn(Unknown(Internal))) | (NoJoin(wrap, tys), Ana(ana)) => let syn: Typ.t = wrap(Unknown(Internal)); - switch (Typ.join_fix(ctx, ana, syn)) { + switch (Typ.join_fix(ctx, syn, ana)) { | None => InHole(Inconsistent(Expectation({ana, syn}))) | Some(_) => NotInHole( diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 6a94ecabbe..11bdfcc358 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -307,19 +307,11 @@ module rec Typ: { !resolve && eq(ty_name, ty_join) ? Var(name) : ty_join; /* Note: Ordering of Unknown, Var, and Rec above is load-bearing! */ | (Rec(x1, ty1), Rec(x2, ty2)) => - /* TODO: - This code isn't fully correct, as we may be doing - substitution on open terms; if x1 occurs in ty2, - we should be substituting x1 for a fresh variable - in ty2. This is annoying, and should be obviated - by the forthcoming debruijn index implementation - */ let ctx = Ctx.extend_dummy_tvar(ctx, x1); let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); Rec(x1, ty_body); | (Forall(x1, ty1), Forall(x2, ty2)) => - /* See note above in Rec case */ let ctx = Ctx.extend_dummy_tvar(ctx, x1); let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); From 876ba5c2d4ad1db7cdbdbcab3148aa4b9d9c62de Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 30 Aug 2023 18:33:56 -0400 Subject: [PATCH 062/229] Update Elaborator.re --- src/haz3lcore/dynamics/Elaborator.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 8b425bce66..1ec05ee328 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -230,7 +230,7 @@ let rec dhexp_of_uexp = | _ => ddef }; let uniq_id = List.nth(def.ids, 0); - let self_id = "__mutual__" ++ string_of_int(uniq_id); + let self_id = "__mutual__" ++ Id.to_string(uniq_id); let self_var = DHExp.BoundVar(self_id); let (_, substituted_def) = fs From 186d437613a8c7fa282aa21dfd7595d14d536463 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 1 Sep 2023 18:20:42 -0400 Subject: [PATCH 063/229] Update Term.re --- src/haz3lcore/statics/Term.re | 56 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index be84040225..03113807a0 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -239,34 +239,6 @@ module UPat = { | Ap => "Constructor application" | TypeAnn => "Annotation"; - let rec get_var = (pat: t) => { - switch (pat.term) { - | Parens(pat) - | TypeAnn(pat, _) => get_var(pat) - | Var(x) => Some(x) - | Invalid(_) - | EmptyHole - | MultiHole(_) - | Wild - | Int(_) - | Float(_) - | Bool(_) - | String(_) - | Triv - | ListLit(_) - | Cons(_, _) - | Tuple(_) - | Constructor(_) - | Ap(_) => None - }; - }; - - let ctr_name = (p: t): option(Constructor.t) => - switch (p.term) { - | Constructor(name) => Some(name) - | _ => None - }; - let rec is_var = (pat: t) => { switch (pat.term) { | Parens(pat) @@ -313,6 +285,28 @@ module UPat = { } ); + let rec get_var = (pat: t) => { + switch (pat.term) { + | Parens(pat) + | TypeAnn(pat, _) => get_var(pat) + | Var(x) => Some(x) + | Invalid(_) + | EmptyHole + | MultiHole(_) + | Wild + | Int(_) + | Float(_) + | Bool(_) + | String(_) + | Triv + | ListLit(_) + | Cons(_, _) + | Tuple(_) + | Constructor(_) + | Ap(_) => None + }; + }; + let rec get_num_of_vars = (pat: t) => if (is_var(pat)) { Some(1); @@ -369,6 +363,12 @@ module UPat = { | Ap(_) => None } }; + + let ctr_name = (p: t): option(Constructor.t) => + switch (p.term) { + | Constructor(name) => Some(name) + | _ => None + }; }; module UExp = { From 726461a8608407cb8c7b013bb0b6ae71d89c9e0a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 3 Sep 2023 21:31:40 -0400 Subject: [PATCH 064/229] Fixed type-hole-annotated single function bug and casting bug --- src/haz3lcore/statics/Statics.re | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0521f63702..938e859c37 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -52,6 +52,7 @@ let is_recursive = (ctx, p, def, syn: Typ.t) => { | (Some(num_vars), Some(num_fns)) when num_vars != 0 && num_vars == num_fns => switch (Typ.normalize(ctx, syn)) { + | Unknown(_) | Arrow(_) => num_vars == 1 | Prod(syns) when List.length(syns) == num_vars => syns @@ -287,7 +288,7 @@ and uexp_to_info_map = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { ty_p == Typ.Unknown(SynSwitch) && !Typ.eq(ty_fn1, ty_fn2) - ? ty_fn1 : Unknown(SynSwitch); + ? ty_fn1 : ty_p; }; let ana = switch ((def_base.ty, def_base2.ty), p_syn.ty) { From 0beba60e4776577096572923db5b0bb6b6d063c3 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 9 Jul 2023 21:54:32 +0800 Subject: [PATCH 065/229] Add some function from injection paper. --- src/haz3lcore/dynamics/Incon.re | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/haz3lcore/dynamics/Incon.re diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re new file mode 100644 index 0000000000..a5d4b8ded2 --- /dev/null +++ b/src/haz3lcore/dynamics/Incon.re @@ -0,0 +1,39 @@ +let rec matches = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (_, Var(_)) => true + | (_, Wild) => true + | (BoolLit(x), BoolLit(y)) => x == y + | (IntLit(x), IntLit(y)) => x == y + | (FloatLit(x), FloatLit(y)) => x == y + | (StringLit(x), StringLit(y)) => x == y + | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) + // I don't know how to extend the algorithm for projection into that of list or tuples. + | (_, _) => false + }; + +let rec is_val = (e: DHExp.t): bool => + switch (e) { + | BoolLit(_) + | IntLit(_) + | StringLit(_) + | Fun(_, _, _, _) + | ListLit(_, _, _, _, []) + | Tuple([]) => true + | ListLit(_, _, _, _, inner) + | Tuple(inner) => + List.fold_left((last_val, e) => last_val && is_val(e), true, inner) + | BinBoolOp(_, e1, e2) + | BinIntOp(_, e1, e2) + | BinFloatOp(_, e1, e2) + | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false + | Inj(_, _, e) => is_val(e) + | _ => false + }; + +let rec is_indet = (e: DHExp.t): bool => + switch (e) { + | EmptyHole(_, _) => true + | NonEmptyHole(_, _, _, e) => is_final(e) + | _ => false + } +and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); From 414ddffba3b83b086e51e43b7dba085ca128f220 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 16 Jul 2023 11:59:57 +0800 Subject: [PATCH 066/229] Finished implementing algorithms from P8. --- src/haz3lcore/dynamics/Incon.re | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index a5d4b8ded2..2d403e1174 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -7,10 +7,35 @@ let rec matches = (e: DHExp.t, p: DHPat.t): bool => | (FloatLit(x), FloatLit(y)) => x == y | (StringLit(x), StringLit(y)) => x == y | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know how to extend the algorithm for projection into that of list or tuples. + // I don't know if my algorithm is correct or not. + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => true + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) | (_, _) => false }; +let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => + switch (e, p) { + | (BoolLit(x), BoolLit(y)) => x != y + | (IntLit(x), IntLit(y)) => x != y + | (FloatLit(x), FloatLit(y)) => x != y + | (StringLit(x), StringLit(y)) => x != y + | (ListLit(_, _, _, _, []), ListLit(_, [])) + | (Tuple([]), Tuple([])) => false + | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) + | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => + does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) + | (Inj(_, side1, x), Inj(side2, y)) => + side1 != side2 || does_not_match(x, y) + | (_, _) => false + }; + +// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. +let indet_match = (e: DHExp.t, p: DHPat.t): bool => + !(matches(e, p) || does_not_match(e, p)); + let rec is_val = (e: DHExp.t): bool => switch (e) { | BoolLit(_) From 5b3df76944567c6ffbea539d2427cee03466fb8d Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Fri, 21 Jul 2023 18:10:34 +0800 Subject: [PATCH 067/229] Translating part of old Constraint.re into this version. --- src/haz3lcore/dynamics/Constraint.re | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/haz3lcore/dynamics/Constraint.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re new file mode 100644 index 0000000000..c94c805f29 --- /dev/null +++ b/src/haz3lcore/dynamics/Constraint.re @@ -0,0 +1,41 @@ +open Sexplib.Std; + +[@deriving sexp] +type t = + | Truth + | Falsity + | Hole + | Int(int) + | NotInt(int) + | Float(float) + | NotFloat(float) + | String(string) + | NotString(string) + | And(t, t) + | Or(t, t) + | InjL(t) + | InjR(t) + | List(list(t)); + +// How to replace this function? +let rec constrains = (c: t, ty: HTyp.t): bool => + switch (c, ty) { + // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { + | (Truth, _) + | (Falsity, _) + | (Hole, _) => true + | (Int(_) | NotInt(_), Int) => true + | (Int(_) | NotInt(_), _) => false + | (Float(_) | NotFloat(_), Float) => true + | (Float(_) | NotFloat(_), _) => false + | (String(_) | NotString(_), String) => true + | (String(_) | NotString(_), _) => false + | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + | (InjL(_), _) => false + | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(_), _) => false + | (List(c), ty) => + List.fold_left((last, x) => last && constrains(x, ty), true, c) + }; From 16e1ba48df66f8809c00a95d7b44ea70f7eaf0a8 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Tue, 1 Aug 2023 21:16:36 +0800 Subject: [PATCH 068/229] Rebase, Part 1. --- src/haz3lcore/dynamics/InvalidOperationError.re | 4 ++++ src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index ce8c94e888..858e7b0757 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -5,6 +5,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel + | InvalidIntOfString + | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -14,5 +16,7 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" + | InvalidIntOfString => "Error: Invalid String to Int Conversion" + | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 2dc53757b5..ead18ee4ff 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -179,7 +179,7 @@ let rec mk = | BoolLit(b) => DHDoc_common.mk_BoolLit(b) | IntLit(n) => DHDoc_common.mk_IntLit(n) | FloatLit(f) => DHDoc_common.mk_FloatLit(f) - | StringLit(s) => DHDoc_common.mk_StringLit(s) + | StringLit(s) => DHDoc_common.mk_StringLit("\"" ++ s ++ "\"") | TestLit(_) => Doc.text(ExpandingKeyword.to_string(Test)) | Sequence(d1, d2) => let (doc1, doc2) = (go'(d1), go'(d2)); From aba862e24adf100e7a2b8e797e4b450a32485452 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Mon, 7 Aug 2023 22:23:42 +0800 Subject: [PATCH 069/229] Rebase, Part 2. --- src/haz3lcore/dynamics/Constraint.re | 112 +++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c94c805f29..c8e4bee946 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -18,9 +18,11 @@ type t = | List(list(t)); // How to replace this function? -let rec constrains = (c: t, ty: HTyp.t): bool => - switch (c, ty) { - // switch (c, HTyp.head_normalize(InitialContext.ctx, ty)) { +let rec constrains = (c: t, ty: Typ.t): bool => + switch ( + c, + Typ.weak_head_normalize(Builtins.ctx(Builtins.Pervasives.builtins), ty), + ) { | (Truth, _) | (Falsity, _) | (Hole, _) => true @@ -32,10 +34,110 @@ let rec constrains = (c: t, ty: HTyp.t): bool => | (String(_) | NotString(_), _) => false | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) - | (InjL(c1), Sum(ty1, _)) => constrains(c1, ty1) + // Treates sum as if it is left associative + | (InjL(c1), Sum(map)) => + switch (List.hd(map)) { + | (_, Some(ty1)) => constrains(c1, ty1) + | _ => false + } | (InjL(_), _) => false - | (InjR(c2), Sum(_, ty2)) => constrains(c2, ty2) + | (InjR(c2), Sum(map)) => + switch (List.tl(map)) { + | [] => false + | [(_, Some(ty2))] => constrains(c2, ty2) + | map' => constrains(c2, Sum(map')) + } | (InjR(_), _) => false | (List(c), ty) => List.fold_left((last, x) => last && constrains(x, ty), true, c) }; + +let rec or_constraints = (lst: list(t)): t => + switch (lst) { + | [] => failwith("should have at least one constraint") + | [xi] => xi + | [xi, ...xis] => Or(xi, or_constraints(xis)) + }; + +let rec dual = (c: t): t => + switch (c) { + | Truth => Falsity + | Falsity => Truth + | Hole => Hole + | Int(n) => NotInt(n) + | NotInt(n) => Int(n) + | Float(n) => NotFloat(n) + | NotFloat(n) => Float(n) + | String(n) => NotString(n) + | NotString(n) => String(n) + | And(c1, c2) => Or(dual(c1), dual(c2)) + | Or(c1, c2) => And(dual(c1), dual(c2)) + | InjL(c1) => Or(InjL(dual(c1)), InjR(Truth)) + | InjR(c2) => Or(InjR(dual(c2)), InjL(Truth)) + // Thought: generate all combinations of ways to dual the list (2^n - 1), and connect them with or + | List(l) => + let permutation = List.map(l' => List(l'), List.tl(permutate(l))); + // ``Or'' is associative, so I try to use this way to simplify it + or_constraints(permutation); + } +and permutate = (l: list(t)): list(list(t)) => + switch (l) { + | [] => [[]] + | [hd, ...tl] => + let result_tl = permutate(tl); + List.map(l' => [hd, ...l'], result_tl) + @ List.map(l' => [dual(hd), ...l'], result_tl); + }; + +/** substitute Truth for Hole */ +let rec truify = (c: t): t => + switch (c) { + | Hole => Truth + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(truify(c1), truify(c2)) + | Or(c1, c2) => Or(truify(c1), truify(c2)) + | InjL(c) => InjL(truify(c)) + | InjR(c) => InjR(truify(c)) + | List(l) => List.map(c => truify(c), l) + }; + +/** substitute Falsity for Hole */ +let rec falsify = (c: t): t => + switch (c) { + | Hole => Falsity + | Truth + | Falsity + | Int(_) + | NotInt(_) + | Float(_) + | NotFloat(_) + | String(_) + | NotString(_) => c + | And(c1, c2) => And(falsify(c1), falsify(c2)) + | Or(c1, c2) => Or(falsify(c1), falsify(c2)) + | InjL(c) => InjL(falsify(c)) + | InjR(c) => InjR(falsify(c)) + | List(l) => List.map(c => falsify(c), l) + }; + +let unwrapL = + fun + | InjL(c) => c + | _ => failwith("input can only be InjL(_)"); + +let unwrapR = + fun + | InjR(c) => c + | _ => failwith("input can only be InjR(_)"); + +let unwrap_list = + fun + | List(l) => l + | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file From 2e526d4a44f07756a2e0c8e94f29cf43757e97c4 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 16 Aug 2023 18:38:12 +0800 Subject: [PATCH 070/229] Ported `Incon.re` and `Sets.re`. --- src/haz3lcore/dynamics/Constraint.re | 6 +- src/haz3lcore/dynamics/Incon.re | 296 +++++++++++++++++++++------ src/haz3lcore/dynamics/Sets.re | 23 +++ 3 files changed, 265 insertions(+), 60 deletions(-) create mode 100644 src/haz3lcore/dynamics/Sets.re diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c8e4bee946..1388e2fde6 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -105,7 +105,7 @@ let rec truify = (c: t): t => | Or(c1, c2) => Or(truify(c1), truify(c2)) | InjL(c) => InjL(truify(c)) | InjR(c) => InjR(truify(c)) - | List(l) => List.map(c => truify(c), l) + | List(l) => List(List.map(c => truify(c), l)) }; /** substitute Falsity for Hole */ @@ -124,7 +124,7 @@ let rec falsify = (c: t): t => | Or(c1, c2) => Or(falsify(c1), falsify(c2)) | InjL(c) => InjL(falsify(c)) | InjR(c) => InjR(falsify(c)) - | List(l) => List.map(c => falsify(c), l) + | List(l) => List(List.map(c => falsify(c), l)) }; let unwrapL = @@ -140,4 +140,4 @@ let unwrapR = let unwrap_list = fun | List(l) => l - | _ => failwith("input can only be List([_, ..._])"); \ No newline at end of file + | _ => failwith("input can only be List([_, ..._])"); diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 2d403e1174..204d181cb6 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -1,64 +1,246 @@ -let rec matches = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (_, Var(_)) => true - | (_, Wild) => true - | (BoolLit(x), BoolLit(y)) => x == y - | (IntLit(x), IntLit(y)) => x == y - | (FloatLit(x), FloatLit(y)) => x == y - | (StringLit(x), StringLit(y)) => x == y - | (Inj(_, side1, x), Inj(side2, y)) => side1 == side2 && matches(x, y) - // I don't know if my algorithm is correct or not. - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => true - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - matches(hd1, hd2) && matches(Tuple(tl1), Tuple(tl2)) - | (_, _) => false +open Sets; + +let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { + let (int_set, not_int_list) = + List.fold_left( + ((int_set, not_int_list), xi: Constraint.t) => + switch (xi) { + | Int(n) => (IntSet.add(n, int_set), not_int_list) + | NotInt(n) => (int_set, [n, ...not_int_list]) + | _ => failwith("input can only be Int | NotInt") + }, + (IntSet.empty, []), + xis, + ); + if (IntSet.cardinal(int_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + IntSet.mem(n, int_set); + }, + false, + not_int_list, + ); }; +}; -let rec does_not_match = (e: DHExp.t, p: DHPat.t): bool => - switch (e, p) { - | (BoolLit(x), BoolLit(y)) => x != y - | (IntLit(x), IntLit(y)) => x != y - | (FloatLit(x), FloatLit(y)) => x != y - | (StringLit(x), StringLit(y)) => x != y - | (ListLit(_, _, _, _, []), ListLit(_, [])) - | (Tuple([]), Tuple([])) => false - | (ListLit(_, _, _, _, [hd1, ...tl1]), ListLit(_, [hd2, ...tl2])) - | (Tuple([hd1, ...tl1]), Tuple([hd2, ...tl2])) => - does_not_match(hd1, hd2) || does_not_match(Tuple(tl1), Tuple(tl2)) - | (Inj(_, side1, x), Inj(side2, y)) => - side1 != side2 || does_not_match(x, y) - | (_, _) => false +let is_inconsistent_float = (xis: list(Constraint.t)): bool => { + let (float_set, not_float_list) = + List.fold_left( + ((float_set, not_float_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (FloatSet.add(n, float_set), not_float_list) + | NotFloat(n) => (float_set, [n, ...not_float_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (FloatSet.empty, []), + xis, + ); + if (FloatSet.cardinal(float_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + FloatSet.mem(n, float_set); + }, + false, + not_float_list, + ); }; +}; -// It is difficult to write indet_match, so I used the theorem to simplify it. Probably it will execute slower. -let indet_match = (e: DHExp.t, p: DHPat.t): bool => - !(matches(e, p) || does_not_match(e, p)); +let is_inconsistent_string = (xis: list(Constraint.t)): bool => { + let (string_set, not_string_list) = + List.fold_left( + ((string_set, not_string_list), xi: Constraint.t) => + switch (xi) { + | Float(n) => (StringSet.add(n, string_set), not_string_list) + | NotFloat(n) => (string_set, [n, ...not_string_list]) + | _ => failwith("input can only be Float | NotFloat") + }, + (StringSet.empty, []), + xis, + ); + if (StringSet.cardinal(string_set) > 1) { + true; + } else { + List.fold_left( + (incon, n) => + if (incon) { + incon; + } else { + StringSet.mem(n, string_set); + }, + false, + not_string_list, + ); + }; +}; -let rec is_val = (e: DHExp.t): bool => - switch (e) { - | BoolLit(_) - | IntLit(_) - | StringLit(_) - | Fun(_, _, _, _) - | ListLit(_, _, _, _, []) - | Tuple([]) => true - | ListLit(_, _, _, _, inner) - | Tuple(inner) => - List.fold_left((last_val, e) => last_val && is_val(e), true, inner) - | BinBoolOp(_, e1, e2) - | BinIntOp(_, e1, e2) - | BinFloatOp(_, e1, e2) - | BinStringOp(_, e1, e2) => is_val(e1) ? is_val(e2) : false - | Inj(_, _, e) => is_val(e) - | _ => false +let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => + switch (xis) { + | [] => false + | [xi, ...xis'] => + switch (xi) { + | Truth => is_inconsistent(~may, xis') + | Falsity => true + | Hole => may ? true : is_inconsistent(~may, xis') + | And(xi1, xi2) => is_inconsistent(~may, [xi1, xi2, ...xis']) + | Or(xi1, xi2) => + is_inconsistent(~may, [xi1, ...xis']) + && is_inconsistent(~may, [xi2, ...xis']) + | InjL(_) => + if (List.exists( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + ) + ) { + | (injLs, []) => + let unwrap = List.map(Constraint.unwrapL, injLs); + is_inconsistent(~may, unwrap); + | (injLs, other) => is_inconsistent(~may, other @ injLs) + }; + } + | InjR(_) => + if (List.exists( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + )) { + true; + } else { + switch ( + List.partition( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + ) + ) { + | (injRs, []) => + let unwrap = List.map(Constraint.unwrapR, injRs); + is_inconsistent(~may, unwrap); + | (injRs, other) => is_inconsistent(~may, other @ injRs) + }; + } + | Int(_) + | NotInt(_) => + switch ( + List.partition( + fun + | Constraint.Int(_) + | NotInt(_) => true + | _ => false, + xis, + ) + ) { + | (ns, []) => is_inconsistent_nums(ns) + | (ns, other) => is_inconsistent(~may, other @ ns) + } + | Float(_) + | NotFloat(_) => + switch ( + List.partition( + fun + | Constraint.Float(_) + | NotFloat(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_float(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + | String(_) + | NotString(_) => + switch ( + List.partition( + fun + | Constraint.String(_) + | NotString(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_string(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } + /* + * Thoughts for porting the Pair judgment to list: + * Two list constraints are automatically inconsistent if they have different length. + * So we first find maximum and minimum list lengths, and determine if they are the same. + * If so, we rearrange them in item-first order, and check each of them. + */ + | List(_) => + switch ( + List.partition( + fun + | Constraint.List(_) => true + | _ => false, + xis, + ) + ) { + | (lists, []) => + let lengths = + List.map(x => List.length(Constraint.unwrap_list(x)), lists); + // check if all lengths are equal + // This could be done with exceptions, but I found nothing related on ReasonML website. + let all_lengths_are_equal = + List.for_all(x => x == List.hd(lengths), List.tl(lengths)); + if (all_lengths_are_equal) { + let order_by_index = + List.fold_left( + // ordered_by_index: list(list(t)); item: packed version of list(t) + (ordered_by_index, lst) => + List.map2( + // We need a function that maps `(list(t), t)` to list(list(t) + (old_list, item) => [item, ...old_list], + ordered_by_index, + Constraint.unwrap_list(lst), + ), + // Initial version of empty list, in list(list(t)) + List.map(x => [x], Constraint.unwrap_list(List.hd(lists))), + // Rest of items + List.tl(lists), + ); + // Check if there are inconsistency in each element + List.fold_left( + (previous, item) => previous || is_inconsistent(~may, item), + may, + order_by_index, + ); + } else { + true; // Automatically inconsistent + }; + | (lists, other) => is_inconsistent(~may, other @ lists) + } + } }; -let rec is_indet = (e: DHExp.t): bool => - switch (e) { - | EmptyHole(_, _) => true - | NonEmptyHole(_, _, _, e) => is_final(e) - | _ => false - } -and is_final = (e: DHExp.t): bool => is_val(e) && is_indet(e); +let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => + is_inconsistent( + ~may=false, + Constraint.[And(truify(xi_cur), dual(falsify(xi_pre)))], + ); + +let is_exhaustive = (xi: Constraint.t): bool => + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file diff --git a/src/haz3lcore/dynamics/Sets.re b/src/haz3lcore/dynamics/Sets.re new file mode 100644 index 0000000000..67b6099709 --- /dev/null +++ b/src/haz3lcore/dynamics/Sets.re @@ -0,0 +1,23 @@ +module IntSet = + Set.Make({ + type t = int; + let compare = compare; + }); + +module BoolSet = + Set.Make({ + type t = bool; + let compare = compare; + }); + +module FloatSet = + Set.Make({ + type t = float; + let compare = compare; + }); + +module StringSet = + Set.Make({ + type t = float; + let compare = compare; + }); From 841224fad5398f9b23af1f648fd2a139d432b447 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 10 Sep 2023 17:09:26 -0400 Subject: [PATCH 071/229] Rebasing trial 2 step 1. --- opam.export | 94 ++++++++++++++++----------------- src/haz3lcore/dynamics/Incon.re | 2 +- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/opam.export b/opam.export index 0928befbcc..44e4bd2db1 100644 --- a/opam.export +++ b/opam.export @@ -3,20 +3,20 @@ compiler: ["ocaml-base-compiler.5.0.0"] roots: [ "ezjs_idb.0.1.1" "incr_dom.v0.15.1" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" - "merlin.4.8-500" + "merlin.4.9-500" "ocaml-base-compiler.5.0.0" - "ocaml-lsp-server.1.15.1-5.0" - "ocamlformat.0.25.1" - "omd.1.3.2" + "ocaml-lsp-server.1.16.2" + "ocamlformat.0.26.0" + "omd.2.0.0~alpha4" "ppx_deriving.5.2.1" "ppx_yojson_conv.v0.15.1" "ptmap.2.0.5" - "reason.3.8.2" - "tezt.3.0.0" + "reason.3.9.0" + "tezt.3.1.1" "unionFind.20220122" - "utop.2.11.0" + "utop.2.13.1" "uuidm.0.9.8" ] installed: [ @@ -38,28 +38,28 @@ installed: [ "bigstringaf.0.9.1" "bin_prot.v0.15.0" "camlp-streams.5.0.1" - "chrome-trace.3.7.0" - "cmdliner.1.1.1" + "chrome-trace.3.10.0" + "cmdliner.1.2.0" "conf-autoconf.0.1" "conf-which.1" "core.v0.15.1" "core_kernel.v0.15.0" "cppo.1.6.9" - "csexp.1.5.1" + "csexp.1.5.2" "cstruct.6.2.0" - "dot-merlin-reader.4.6" - "dune.3.7.0" - "dune-build-info.3.7.0" - "dune-configurator.3.7.0" - "dune-rpc.3.6.2" - "dyn.3.6.2" + "dot-merlin-reader.4.9" + "dune.3.10.0" + "dune-build-info.3.10.0" + "dune-configurator.3.10.0" + "dune-rpc.3.10.0" + "dyn.3.10.0" "either.1.0.0" "ezjs_idb.0.1.1" "ezjs_min.0.3.0" "ezjsonm.1.3.0" - "fiber.3.6.2" + "fiber.3.7.0" "fieldslib.v0.15.0" - "fix.20220121" + "fix.20230505" "fmt.0.9.0" "fpath.0.7.3" "gen.1.1" @@ -71,24 +71,24 @@ installed: [ "incremental.v0.15.0" "int_repr.v0.15.0" "jane-street-headers.v0.15.0" - "js_of_ocaml.4.1.0" - "js_of_ocaml-compiler.4.1.0" - "js_of_ocaml-ppx.4.1.0" + "js_of_ocaml.5.4.0" + "js_of_ocaml-compiler.5.4.0" + "js_of_ocaml-ppx.5.4.0" "jsonm.1.0.2" "jst-config.v0.15.1" - "lambda-term.3.3.1" + "lambda-term.3.3.2" "lambdasoup.1.0.0" "logs.0.7.0" - "lwt.5.6.1" + "lwt.5.7.0" "lwt-dllist.1.0.1" "lwt_react.1.2.0" "markup.1.0.3" - "menhir.20220210" - "menhirLib.20220210" - "menhirSdk.20220210" - "merlin.4.8-500" + "menhir.20230608" + "menhirLib.20230608" + "menhirSdk.20230608" + "merlin.4.9-500" "merlin-extend.0.6.1" - "merlin-lib.4.8-500" + "merlin-lib.4.9-500" "mew.0.1.0" "mew_vi.0.5.0" "num.1.4" @@ -96,28 +96,28 @@ installed: [ "ocaml-base-compiler.5.0.0" "ocaml-compiler-libs.v0.12.4" "ocaml-config.3" - "ocaml-lsp-server.1.15.1-5.0" + "ocaml-lsp-server.1.16.2" "ocaml-options-vanilla.1" "ocaml-syntax-shims.1.0.0" "ocaml-version.3.6.1" "ocamlbuild.0.14.2" - "ocamlc-loc.3.6.2" + "ocamlc-loc.3.10.0" "ocamlfind.1.9.6" - "ocamlformat.0.25.1" - "ocamlformat-lib.0.25.1" - "ocamlformat-rpc-lib.0.25.1" + "ocamlformat.0.26.0" + "ocamlformat-lib.0.26.0" + "ocamlformat-rpc-lib.0.26.0" "ocp-indent.1.8.1" "ocplib-endian.1.2" "octavius.1.2.2" "odoc-parser.2.0.0" "ojs.1.1.2" - "omd.1.3.2" - "ordering.3.6.2" + "omd.2.0.0~alpha4" + "ordering.3.10.0" "parsexp.v0.15.0" "pp.1.1.2" "ppx_assert.v0.15.0" "ppx_base.v0.15.0" - "ppx_bench.v0.15.0" + "ppx_bench.v0.15.1" "ppx_bin_prot.v0.15.0" "ppx_cold.v0.15.0" "ppx_compare.v0.15.0" @@ -132,7 +132,7 @@ installed: [ "ppx_hash.v0.15.0" "ppx_here.v0.15.0" "ppx_ignore_instrumentation.v0.15.0" - "ppx_inline_test.v0.15.0" + "ppx_inline_test.v0.15.1" "ppx_jane.v0.15.0" "ppx_js_style.v0.15.0" "ppx_let.v0.15.0" @@ -151,14 +151,14 @@ installed: [ "ppx_variants_conv.v0.15.0" "ppx_yojson_conv.v0.15.1" "ppx_yojson_conv_lib.v0.15.0" - "ppxlib.0.28.0" + "ppxlib.0.30.0" "protocol_version_header.v0.15.0" "ptmap.2.0.5" "re.1.10.4" "react.1.2.2" - "reason.3.8.2" + "reason.3.9.0" "result.1.5" - "sedlex.3.1" + "sedlex.3.2" "seq.base" "sexplib.v0.15.1" "sexplib0.v0.15.1" @@ -167,9 +167,9 @@ installed: [ "stdcompat.19" "stdio.v0.15.0" "stdlib-shims.0.3.0" - "stdune.3.6.2" + "stdune.3.10.0" "stringext.1.6.0" - "tezt.3.0.0" + "tezt.3.1.1" "time_now.v0.15.0" "topkg.1.0.7" "trie.1.0.0" @@ -179,7 +179,7 @@ installed: [ "unionFind.20220122" "uri.4.2.0" "uri-sexp.4.2.0" - "utop.2.11.0" + "utop.2.13.1" "uucp.15.0.0" "uuidm.0.9.8" "uunf.15.0.0" @@ -187,9 +187,9 @@ installed: [ "uutf.1.0.3" "variantslib.v0.15.0" "virtual_dom.v0.15.1" - "xdg.3.7.0" - "yojson.2.0.2" - "zed.3.2.1" + "xdg.3.10.0" + "yojson.2.1.0" + "zed.3.2.3" ] pinned: [ "async_js.v0.15.1" diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 204d181cb6..8b9bd7b02d 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -243,4 +243,4 @@ let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => ); let is_exhaustive = (xi: Constraint.t): bool => - is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); \ No newline at end of file + is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); From 1635b427f4a78d51343bc1c5f1e4f6e583ebfac7 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Tue, 1 Aug 2023 21:16:36 +0800 Subject: [PATCH 072/229] Rebase the project on `adt_defs_after` instead of `dev`. --- src/haz3lcore/tiles/Id.re | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/haz3lcore/tiles/Id.re b/src/haz3lcore/tiles/Id.re index c4f3af6036..388087cc11 100644 --- a/src/haz3lcore/tiles/Id.re +++ b/src/haz3lcore/tiles/Id.re @@ -32,6 +32,73 @@ */ +/* ID FAQ + + WHAT ARE IDS USED FOR? + + Unique ids are assigned to tiles (and hence, indirectly, to terms) + at the time of creation of surface syntax. Ids are used as keys in + various maps (mostly notably the Measured map, which tracks screen + coordinates for the view, and the Info map which collects static + data such as type information). + + BUT WHY IS THERE A _LIST_ OF IDS? + + Technically, each tile has a list of ids, to support n-ary forms like + tuples; there are rep_id functions in Term to canonically extract + single representative ids from this list where appropriate. + + HOW ARE NEW IDS CREATED? + + In the parts of the implementation which manipulate Zippers, fresh id + creation is done by threading an IdGen parameter through all of the + (functions which call) functions where new tiles can be created. This + generally follows the state monad pattern. When a fresh Id is required, + the current value of the IdGen is used, and the IdGen is incremented + and must then be returned to the caller. + + The threading of IdGen through essentially all syntax modification + functions presents a significant complication for the action code, + and may eventually be replaced it with a mutable ref. + + WHERE DOES IDGEN LIVE? + + The initial IdGen passed to zipper functions is generally packaged + along with a zipper through the Zipper.state type. Although in + principle the initial IdGen could be set by traversing the zipper + and finding the largest Id, to avoid this traversal we track the + IdGen along with the zipper state. Each editor mode is responsible + for this tracking. Ultimately, each zipper action which can result in + new Ids being created must be sandwiched by calls to + Editors.get_editor_and_id and Editors.put_editor_and_id, to ensure that + IdGen state is tracked between actions and properly serialized to + local storage. + + HOW DO I GENERATE FRESH IDS FOR MY USE CASE? + + Currently there is no easy way to generate fresh IDs in places one + might concievably want them after Term creation, for example in the + elaborator or evaluator. Doing so is a significant change with + indirect implications for architrcture and performance; ask Andrew + about your use case before attempting this. For some uses, a dummy id + may be sufficient; this should be documented and use Id.invalid or + another similar label rather than magic literals. If you do need to + generated genuinely fresh IDs, then you'll need (A) a strategy + to route an IdGen to/from your use site to the aformentioned + Editors functions, and a traversal/mutation strategy within your + context of use. + + IDS IN DYNAMICS: + + Currently, DHExps (as produced by the elaborator and produced/consumed + by the evaluator) do not in general persist ids; the exceptions are + things like holes and tests which have additional metadata which is + accumulated duting evaluation. There are many use cases for tracking + ids more generally during evaluation, but doing so in a principled + way is a large-scale change with architectural implications. + + */ + [@deriving (show({with_path: false}), sexp, yojson)] let sexp_of_t: Uuidm.t => Sexplib.Sexp.t = t => Sexplib.Sexp.Atom(Uuidm.to_string(t)); From 4da6ccb329fad06b964a5fc354ff20dde1bda75f Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sun, 27 Aug 2023 09:54:46 -0400 Subject: [PATCH 073/229] Fixed a bug related to incomplete rebasing. --- src/haz3lcore/dynamics/Constraint.re | 5 +---- src/haz3lcore/dynamics/InvalidOperationError.re | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 1388e2fde6..0a4b705a2d 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -19,10 +19,7 @@ type t = // How to replace this function? let rec constrains = (c: t, ty: Typ.t): bool => - switch ( - c, - Typ.weak_head_normalize(Builtins.ctx(Builtins.Pervasives.builtins), ty), - ) { + switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { | (Truth, _) | (Falsity, _) | (Hole, _) => true diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index 858e7b0757..3a6e31c35f 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -5,8 +5,8 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel - | InvalidIntOfString - | InvalidFloatOfString + // | InvalidIntOfString + // | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -16,7 +16,7 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" - | InvalidIntOfString => "Error: Invalid String to Int Conversion" - | InvalidFloatOfString => "Error: Invalid String to Float Conversion" + // | InvalidIntOfString => "Error: Invalid String to Int Conversion" + // | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; From 60696767800b6e5570c6ef7d702bbd2a0a0c194a Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sun, 10 Sep 2023 23:50:45 -0400 Subject: [PATCH 074/229] Allow type names to be lowercase. --- src/haz3lcore/lang/Form.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index ae23e84aa8..95be7b05d5 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -93,7 +93,7 @@ let is_capitalized_name = regexp("^[A-Z][A-Za-z0-9_]*$"); let is_ctr = is_capitalized_name; let base_typs = ["String", "Int", "Float", "Bool"]; let is_base_typ = regexp("^(" ++ String.concat("|", base_typs) ++ ")$"); -let is_typ_var = is_capitalized_name; +let is_typ_var = str => is_var(str) || is_capitalized_name(str); let wild = "_"; let is_wild = regexp("^" ++ wild ++ "$"); From b0298edafb4ca84a258b3cca2a86dc19e2f3f7f8 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 12 Sep 2023 03:32:19 -0400 Subject: [PATCH 075/229] Improve clarity of type outputs by fixing some parentheses. --- src/haz3lweb/view/Type.re | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index ed08e6099e..84d10c51dc 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -34,7 +34,7 @@ let needs_parens = (ty: Haz3lcore.Typ.t): bool => | Sum(_) => true /* disambiguate between (A + B) -> C and A + (B -> C) */ }; -let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => +let rec view_ty = (~strip_outer_parens=false, ty: Haz3lcore.Typ.t): Node.t => switch (ty) { | Unknown(prov) => div( @@ -53,12 +53,12 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Rec(name, t) => div( ~attr=clss(["typ-view", "Rec"]), - [text("rec " ++ name ++ ". "), view_ty(t)], + [text("rec " ++ name ++ ". "), ...paren_view(t)], ) | Forall(name, t) => div( ~attr=clss(["typ-view", "Forall"]), - [text("forall " ++ name ++ ". "), view_ty(t)], + [text("forall " ++ name ++ ". "), ...paren_view(t)], ) | List(t) => div( @@ -76,8 +76,14 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => | Prod([t0, ...ts]) => div( ~attr=clss(["typ-view", "atom", "Prod"]), - [ - text("("), + ( + if (!strip_outer_parens) { + [text("(")]; + } else { + []; + } + ) + @ [ div( ~attr=clss(["typ-view", "Prod"]), paren_view(t0) @@ -86,8 +92,14 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => |> List.flatten ), ), - text(")"), - ], + ] + @ ( + if (!strip_outer_parens) { + [text(")")]; + } else { + []; + } + ), ) | Sum(ts) => div( @@ -105,7 +117,11 @@ let rec view_ty = (ty: Haz3lcore.Typ.t): Node.t => and ctr_view = ((ctr, typ)) => switch (typ) { | None => [text(ctr)] - | Some(typ) => [text(ctr ++ "("), view_ty(typ), text(")")] + | Some(typ) => [ + text(ctr ++ "("), + view_ty(~strip_outer_parens=true, typ), + text(")"), + ] } and paren_view = typ => if (needs_parens(typ)) { From 6f62655ef934468df71201b8c4506c41ca71adc0 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 12 Sep 2023 03:32:29 -0400 Subject: [PATCH 076/229] Add langdocs and examples for forall and rec. --- src/haz3lweb/LangDocMessages.re | 60 +++++++++++++++++++++++++++++++++ src/haz3lweb/view/LangDoc.re | 4 +-- src/haz3lweb/view/Type.re | 2 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/haz3lweb/LangDocMessages.re b/src/haz3lweb/LangDocMessages.re index aebf0ea835..46cd4cddd8 100644 --- a/src/haz3lweb/LangDocMessages.re +++ b/src/haz3lweb/LangDocMessages.re @@ -60,6 +60,8 @@ let mk_parens_typ = Example.mk_tile(Form.get("parens_typ")); let mk_list_exp = Example.mk_tile(Form.get("list_lit_exp")); let mk_list_pat = Example.mk_tile(Form.get("list_lit_pat")); let mk_list_typ = Example.mk_tile(Form.get("list_typ")); +let mk_forall_typ = Example.mk_tile(Form.get("forall")); +let mk_rec_typ = Example.mk_tile(Form.get("rec")); let arrow = () => Example.mk_monotile(Form.get("type-arrow")); let unary_minus = () => Example.mk_monotile(Form.get("unary_minus")); let unary_not = () => Example.mk_monotile(Form.get("not")); @@ -95,6 +97,7 @@ let comma_typ = () => Example.mk_monotile(Form.get("comma_typ")); let nil = () => exp("[]"); let typeann = () => Example.mk_monotile(Form.get("typeann")); let mk_fun = Example.mk_tile(Form.get("fun_")); +let mk_typfun = Example.mk_tile(Form.get("typfun")); let mk_ap_exp = Example.mk_tile(Form.get("ap_exp")); let mk_ap_pat = Example.mk_tile(Form.get("ap_pat")); let mk_let = Example.mk_tile(Form.get("let_")); @@ -369,6 +372,21 @@ let ap_fun_ex = { message: "When given a Some constructor argument, the function evaluates to the constructor's argument.", feedback: Unselected, }; +let poly_id_ex = { + sub_id: "poly_id_ex", + term: + mk_example( + "let id : \n forall X . (X -> X) = \n typfun X -> \n fun x : X -> x \n in id", + ), + message: "The polymorphic identity function. It may be instantiated at any type X, after which the function acts as type (X -> X).", + feedback: Unselected, +}; +let peano_ex = { + sub_id: "peano_ex", + term: mk_example("type Peano = \n rec P . Z + S(P) \n in S(S(S(Z)))"), + message: "The type of the Peano numbers and the representation of the number 3.", + feedback: Unselected, +}; // TODO for shared examples, should the feedback be stored separately for each "instance"? let _pat_body_function_exp_coloring_ids = (sf_pat_id: Id.t, sf_body_id: Id.t, ~pat_id: Id.t, ~body_id: Id.t) @@ -3163,6 +3181,44 @@ let list_typ: form = { }; }; +let forall_typ_group = "forall_typ_group"; +let forall_typ: form = { + let explanation = { + message: "Polymorphic type. The forall binds a type variable that can later be instantiated at a concrete type.", + feedback: Unselected, + }; + { + id: "forall_typ", + syntactic_form: [ + mk_forall_typ([[space(), _tpat, space()]]), + space(), + typ("ty_body"), + ], + expandable_id: None, + explanation, + examples: [poly_id_ex], + }; +}; + +let rec_typ_group = "rec_typ_group"; +let rec_typ: form = { + let explanation = { + message: "Recursive type. The type this represents is the least fixed point of a type constructor operating on the bound type variable.", + feedback: Unselected, + }; + { + id: "rec_typ", + syntactic_form: [ + mk_rec_typ([[space(), _tpat, space()]]), + space(), + typ("ty_body"), + ], + expandable_id: None, + explanation, + examples: [peano_ex], + }; +}; + let arrow_typ_group = "arrow_typ_group"; let arrow3_typ_group = "arrow3_typ_group"; let _typ_arg = typ("ty_arg"); @@ -3584,6 +3640,8 @@ let init = { bool_typ, str_typ, list_typ, + forall_typ, + rec_typ, arrow_typ, arrow3_typ, labelled_sum_typ, @@ -3970,6 +4028,8 @@ let init = { (bool_typ_group, init_options([(bool_typ.id, [])])), (str_typ_group, init_options([(str_typ.id, [])])), (list_typ_group, init_options([(list_typ.id, [])])), + (forall_typ_group, init_options([(forall_typ.id, [])])), + (rec_typ_group, init_options([(rec_typ.id, [])])), (arrow_typ_group, init_options([(arrow_typ.id, [])])), ( arrow3_typ_group, diff --git a/src/haz3lweb/view/LangDoc.re b/src/haz3lweb/view/LangDoc.re index d07e4c4da9..79dfac0fe2 100644 --- a/src/haz3lweb/view/LangDoc.re +++ b/src/haz3lweb/view/LangDoc.re @@ -2829,8 +2829,8 @@ let get_doc = | Parens(_) => default // Shouldn't be hit? | Invalid(_) => default // TODO (typfun): Add langdoc - | Forall(_) => default - | Rec(_) => default + | Forall(_, _) => basic_info(LangDocMessages.forall_typ_group) + | Rec(_) => basic_info(LangDocMessages.rec_typ_group) } | Some(InfoTPat(info)) => switch (info.term.term) { diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index 84d10c51dc..6e53ae5834 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -125,7 +125,7 @@ and ctr_view = ((ctr, typ)) => } and paren_view = typ => if (needs_parens(typ)) { - [text("("), view_ty(typ), text(")")]; + [text("("), view_ty(~strip_outer_parens=true, typ), text(")")]; } else { [view_ty(typ)]; }; From 7ba2672af57bed7f5276cd5e701d6d41aa74621d Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 13 Sep 2023 07:16:00 -0400 Subject: [PATCH 077/229] Rebasing trial 2 step 2. --- src/haz3lcore/zipper/Touched.re | 4 +++- src/haz3lweb/util/JsUtil.re | 3 +-- src/haz3lweb/util/WeakMap.re | 6 ++---- src/lwtutil/Lwt_timed.re | 8 ++++++-- src/pretty/Box.rei | 4 +++- src/pretty/MeasuredLayout.rei | 4 +++- src/util/Monads.re | 2 +- src/util/StateMonad.re | 4 +++- src/util/StateMonad.rei | 4 +++- 9 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/haz3lcore/zipper/Touched.re b/src/haz3lcore/zipper/Touched.re index 70644f9c2b..2a428deb28 100644 --- a/src/haz3lcore/zipper/Touched.re +++ b/src/haz3lcore/zipper/Touched.re @@ -1,7 +1,9 @@ include Id.Map; type t = Id.Map.t(Time.t); -module type S = {let touched: t;}; +module type S = { + let touched: t; +}; let update = (t: Time.t, es: list(Effect.t), td: t) => es diff --git a/src/haz3lweb/util/JsUtil.re b/src/haz3lweb/util/JsUtil.re index 87501bbcc1..1b8685f6b3 100644 --- a/src/haz3lweb/util/JsUtil.re +++ b/src/haz3lweb/util/JsUtil.re @@ -11,8 +11,7 @@ let get_elem_by_id = id => { }; let date_now = () => { - %js - new Js.date_now; + [%js new Js.date_now]; }; let timestamp = () => date_now()##valueOf; diff --git a/src/haz3lweb/util/WeakMap.re b/src/haz3lweb/util/WeakMap.re index edf5fda68d..a3ab0951a9 100644 --- a/src/haz3lweb/util/WeakMap.re +++ b/src/haz3lweb/util/WeakMap.re @@ -16,8 +16,7 @@ module JsMap = { let mk: 'k 'v. unit => t('k, 'v) = () => { let c = Js.Unsafe.global##._Map; - %js - new c; + [%js new c]; }; }; @@ -27,8 +26,7 @@ module JsWeakMap = { let mk: 'k 'v. unit => t('k, 'v) = () => { let c = Js.Unsafe.global##._WeakMap; - %js - new c; + [%js new c]; }; }; diff --git a/src/lwtutil/Lwt_timed.re b/src/lwtutil/Lwt_timed.re index 5eeca72433..e17b77e5f8 100644 --- a/src/lwtutil/Lwt_timed.re +++ b/src/lwtutil/Lwt_timed.re @@ -1,8 +1,12 @@ open Lwt.Infix; -module type TIMER = {let delay: (unit => unit, int) => unit;}; +module type TIMER = { + let delay: (unit => unit, int) => unit; +}; -module type S = {let wrap: (int, Lwt.t('a)) => Lwt.t(option('a));}; +module type S = { + let wrap: (int, Lwt.t('a)) => Lwt.t(option('a)); +}; exception TimedOut; module Make = (T: TIMER) => { diff --git a/src/pretty/Box.rei b/src/pretty/Box.rei index f19613be50..67bb197242 100644 --- a/src/pretty/Box.rei +++ b/src/pretty/Box.rei @@ -29,4 +29,6 @@ type t('annot) = | VBox(list(t('annot))) | Annot('annot, t('annot)); -module Make: (MemoTbl.S) => {let mk: Layout.t('annot) => t('annot);}; +module Make: (MemoTbl.S) => { + let mk: Layout.t('annot) => t('annot); + }; diff --git a/src/pretty/MeasuredLayout.rei b/src/pretty/MeasuredLayout.rei index 8ebc6dbf74..428cbb85e6 100644 --- a/src/pretty/MeasuredLayout.rei +++ b/src/pretty/MeasuredLayout.rei @@ -97,4 +97,6 @@ let pos_fold: let next_position: (~indent: int, MeasuredPosition.t, t(_)) => MeasuredPosition.t; -module Make: (MemoTbl.S) => {let mk: Layout.t('annot) => t('annot);}; +module Make: (MemoTbl.S) => { + let mk: Layout.t('annot) => t('annot); + }; diff --git a/src/util/Monads.re b/src/util/Monads.re index 394f695a0e..dea4a3f872 100644 --- a/src/util/Monads.re +++ b/src/util/Monads.re @@ -74,4 +74,4 @@ module Make_Monad_Z = (M: MONAD_ZIP) => { }; module Make_Monad_B = (M: MONAD_BASIC) => - Make_Monad_Z((Make_Zip((Make_Functor(M))))); + Make_Monad_Z(Make_Zip(Make_Functor(M))); diff --git a/src/util/StateMonad.re b/src/util/StateMonad.re index b86fb19fe9..3209f9c1cd 100644 --- a/src/util/StateMonad.re +++ b/src/util/StateMonad.re @@ -1,4 +1,6 @@ -module type STATE = {type t;}; +module type STATE = { + type t; +}; module type S = { type state; diff --git a/src/util/StateMonad.rei b/src/util/StateMonad.rei index 96eed96261..42a668f00e 100644 --- a/src/util/StateMonad.rei +++ b/src/util/StateMonad.rei @@ -5,7 +5,9 @@ /** State type module specification. */ -module type STATE = {type t;}; +module type STATE = { + type t; +}; /** Output of the functor [Make]. From 0e7bbd182d99ee56caba9f73195cbb19a564f7dc Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Wed, 13 Sep 2023 20:39:43 -0400 Subject: [PATCH 078/229] Fixed (?) dependencies and reformat in compilation. --- opam.export | 45 +++++++++++++++++---------------- src/haz3lcore/zipper/Touched.re | 4 +-- src/haz3lweb/util/JsUtil.re | 3 ++- src/haz3lweb/util/WeakMap.re | 6 +++-- src/lwtutil/Lwt_timed.re | 8 ++---- src/pretty/Box.rei | 4 +-- src/pretty/MeasuredLayout.rei | 4 +-- src/util/Monads.re | 2 +- src/util/StateMonad.re | 4 +-- src/util/StateMonad.rei | 4 +-- 10 files changed, 37 insertions(+), 47 deletions(-) diff --git a/opam.export b/opam.export index dff3abe30a..0928befbcc 100644 --- a/opam.export +++ b/opam.export @@ -3,20 +3,20 @@ compiler: ["ocaml-base-compiler.5.0.0"] roots: [ "ezjs_idb.0.1.1" "incr_dom.v0.15.1" - "lwt.5.7.0" + "lwt.5.6.1" "lwt-dllist.1.0.1" - "merlin.4.9-500" + "merlin.4.8-500" "ocaml-base-compiler.5.0.0" - "ocaml-lsp-server.1.16.2" - "ocamlformat.0.26.0" - "omd.2.0.0~alpha4" + "ocaml-lsp-server.1.15.1-5.0" + "ocamlformat.0.25.1" + "omd.1.3.2" "ppx_deriving.5.2.1" "ppx_yojson_conv.v0.15.1" "ptmap.2.0.5" - "reason.3.9.0" - "tezt.3.1.1" + "reason.3.8.2" + "tezt.3.0.0" "unionFind.20220122" - "utop.2.13.1" + "utop.2.11.0" "uuidm.0.9.8" ] installed: [ @@ -38,28 +38,28 @@ installed: [ "bigstringaf.0.9.1" "bin_prot.v0.15.0" "camlp-streams.5.0.1" - "chrome-trace.3.10.0" - "cmdliner.1.2.0" + "chrome-trace.3.7.0" + "cmdliner.1.1.1" "conf-autoconf.0.1" "conf-which.1" "core.v0.15.1" "core_kernel.v0.15.0" "cppo.1.6.9" - "csexp.1.5.2" + "csexp.1.5.1" "cstruct.6.2.0" - "dot-merlin-reader.4.9" - "dune.3.10.0" - "dune-build-info.3.10.0" - "dune-configurator.3.10.0" - "dune-rpc.3.10.0" - "dyn.3.10.0" + "dot-merlin-reader.4.6" + "dune.3.7.0" + "dune-build-info.3.7.0" + "dune-configurator.3.7.0" + "dune-rpc.3.6.2" + "dyn.3.6.2" "either.1.0.0" "ezjs_idb.0.1.1" "ezjs_min.0.3.0" "ezjsonm.1.3.0" - "fiber.3.7.0" + "fiber.3.6.2" "fieldslib.v0.15.0" - "fix.20230505" + "fix.20220121" "fmt.0.9.0" "fpath.0.7.3" "gen.1.1" @@ -71,9 +71,9 @@ installed: [ "incremental.v0.15.0" "int_repr.v0.15.0" "jane-street-headers.v0.15.0" - "js_of_ocaml.5.4.0" - "js_of_ocaml-compiler.5.4.0" - "js_of_ocaml-ppx.5.4.0" + "js_of_ocaml.4.1.0" + "js_of_ocaml-compiler.4.1.0" + "js_of_ocaml-ppx.4.1.0" "jsonm.1.0.2" "jst-config.v0.15.1" "lambda-term.3.3.1" @@ -181,6 +181,7 @@ installed: [ "uri-sexp.4.2.0" "utop.2.11.0" "uucp.15.0.0" + "uuidm.0.9.8" "uunf.15.0.0" "uuseg.15.0.0" "uutf.1.0.3" diff --git a/src/haz3lcore/zipper/Touched.re b/src/haz3lcore/zipper/Touched.re index 2a428deb28..70644f9c2b 100644 --- a/src/haz3lcore/zipper/Touched.re +++ b/src/haz3lcore/zipper/Touched.re @@ -1,9 +1,7 @@ include Id.Map; type t = Id.Map.t(Time.t); -module type S = { - let touched: t; -}; +module type S = {let touched: t;}; let update = (t: Time.t, es: list(Effect.t), td: t) => es diff --git a/src/haz3lweb/util/JsUtil.re b/src/haz3lweb/util/JsUtil.re index 1b8685f6b3..87501bbcc1 100644 --- a/src/haz3lweb/util/JsUtil.re +++ b/src/haz3lweb/util/JsUtil.re @@ -11,7 +11,8 @@ let get_elem_by_id = id => { }; let date_now = () => { - [%js new Js.date_now]; + %js + new Js.date_now; }; let timestamp = () => date_now()##valueOf; diff --git a/src/haz3lweb/util/WeakMap.re b/src/haz3lweb/util/WeakMap.re index a3ab0951a9..edf5fda68d 100644 --- a/src/haz3lweb/util/WeakMap.re +++ b/src/haz3lweb/util/WeakMap.re @@ -16,7 +16,8 @@ module JsMap = { let mk: 'k 'v. unit => t('k, 'v) = () => { let c = Js.Unsafe.global##._Map; - [%js new c]; + %js + new c; }; }; @@ -26,7 +27,8 @@ module JsWeakMap = { let mk: 'k 'v. unit => t('k, 'v) = () => { let c = Js.Unsafe.global##._WeakMap; - [%js new c]; + %js + new c; }; }; diff --git a/src/lwtutil/Lwt_timed.re b/src/lwtutil/Lwt_timed.re index e17b77e5f8..5eeca72433 100644 --- a/src/lwtutil/Lwt_timed.re +++ b/src/lwtutil/Lwt_timed.re @@ -1,12 +1,8 @@ open Lwt.Infix; -module type TIMER = { - let delay: (unit => unit, int) => unit; -}; +module type TIMER = {let delay: (unit => unit, int) => unit;}; -module type S = { - let wrap: (int, Lwt.t('a)) => Lwt.t(option('a)); -}; +module type S = {let wrap: (int, Lwt.t('a)) => Lwt.t(option('a));}; exception TimedOut; module Make = (T: TIMER) => { diff --git a/src/pretty/Box.rei b/src/pretty/Box.rei index 67bb197242..f19613be50 100644 --- a/src/pretty/Box.rei +++ b/src/pretty/Box.rei @@ -29,6 +29,4 @@ type t('annot) = | VBox(list(t('annot))) | Annot('annot, t('annot)); -module Make: (MemoTbl.S) => { - let mk: Layout.t('annot) => t('annot); - }; +module Make: (MemoTbl.S) => {let mk: Layout.t('annot) => t('annot);}; diff --git a/src/pretty/MeasuredLayout.rei b/src/pretty/MeasuredLayout.rei index 428cbb85e6..8ebc6dbf74 100644 --- a/src/pretty/MeasuredLayout.rei +++ b/src/pretty/MeasuredLayout.rei @@ -97,6 +97,4 @@ let pos_fold: let next_position: (~indent: int, MeasuredPosition.t, t(_)) => MeasuredPosition.t; -module Make: (MemoTbl.S) => { - let mk: Layout.t('annot) => t('annot); - }; +module Make: (MemoTbl.S) => {let mk: Layout.t('annot) => t('annot);}; diff --git a/src/util/Monads.re b/src/util/Monads.re index dea4a3f872..394f695a0e 100644 --- a/src/util/Monads.re +++ b/src/util/Monads.re @@ -74,4 +74,4 @@ module Make_Monad_Z = (M: MONAD_ZIP) => { }; module Make_Monad_B = (M: MONAD_BASIC) => - Make_Monad_Z(Make_Zip(Make_Functor(M))); + Make_Monad_Z((Make_Zip((Make_Functor(M))))); diff --git a/src/util/StateMonad.re b/src/util/StateMonad.re index 3209f9c1cd..b86fb19fe9 100644 --- a/src/util/StateMonad.re +++ b/src/util/StateMonad.re @@ -1,6 +1,4 @@ -module type STATE = { - type t; -}; +module type STATE = {type t;}; module type S = { type state; diff --git a/src/util/StateMonad.rei b/src/util/StateMonad.rei index 42a668f00e..96eed96261 100644 --- a/src/util/StateMonad.rei +++ b/src/util/StateMonad.rei @@ -5,9 +5,7 @@ /** State type module specification. */ -module type STATE = { - type t; -}; +module type STATE = {type t;}; /** Output of the functor [Make]. From 55b49529185e8719021be5a342cc86bb8dc3f653 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 13 Sep 2023 22:18:00 -0400 Subject: [PATCH 079/229] Add langdoc for typfun and typap. TODO more cases for typfun. --- src/haz3lweb/LangDocMessages.re | 95 +++++++++++++++++++++++++++++ src/haz3lweb/view/LangDoc.re | 102 +++++++++++++++++++++++--------- 2 files changed, 169 insertions(+), 28 deletions(-) diff --git a/src/haz3lweb/LangDocMessages.re b/src/haz3lweb/LangDocMessages.re index 46cd4cddd8..02920127dc 100644 --- a/src/haz3lweb/LangDocMessages.re +++ b/src/haz3lweb/LangDocMessages.re @@ -100,6 +100,7 @@ let mk_fun = Example.mk_tile(Form.get("fun_")); let mk_typfun = Example.mk_tile(Form.get("typfun")); let mk_ap_exp = Example.mk_tile(Form.get("ap_exp")); let mk_ap_pat = Example.mk_tile(Form.get("ap_pat")); +let mk_tyap_exp = Example.mk_tile(Form.get("ap_exp_typ")); let mk_let = Example.mk_tile(Form.get("let_")); let mk_tyalias = Example.mk_tile(Form.get("type_alias")); @@ -270,6 +271,8 @@ let function_tuple_2_group = "function_tuple_2_group"; let function_tuple_3_group = "function_tuple_3_group"; let function_ctr_group = "function_ctr_group"; let function_ap_group = "function_ap_group"; +let typ_function_group = "typ_function_group"; +let typ_function_hole_group = "typ_function_hole_group"; let basic_fun_ex = { sub_id: "basic_fun_ex", term: mk_example("fun x -> x"), @@ -783,6 +786,83 @@ let function_ap_exp: form = { }; }; +let _tp = tpat("X"); +let _e = exp("e"); + +let typ_fun_pat_coloring_ids = + (~tpat_id: Id.t, ~body_id: Id.t): list((Id.t, Id.t)) => [ + (Piece.id(_tp), tpat_id), + (Piece.id(_e), body_id), +]; + +let typ_function_exp: form = { + let explanation = { + message: "Type function literal. When instantiated at a type that matches the [*argument pattern*](%s), evaluates to the [*body*](%s).", + feedback: Unselected, + }; + let form = [mk_typfun([[space(), _tp, space()]]), space(), _e]; + { + id: "typ_function_exp_id", + syntactic_form: form, + expandable_id: Some(Piece.id(tpat("EmptyHole"))), + explanation, + examples: [poly_id_ex], + }; +}; + +let _tp = tpat("EmptyHole"); +let _e = exp("e"); + +let typ_fun_hole_pat_coloring_ids = + (~tpat_id: Id.t, ~body_id: Id.t): list((Id.t, Id.t)) => [ + (Piece.id(_tp), tpat_id), + (Piece.id(_e), body_id), +]; + +let typ_function_hole: form = { + let explanation = { + message: "Type function literal. When instantiated at a type that matches the [*argument pattern*](%s) after the [empty hole pattern](%s) is filled, evaluates to the [*body*](%s).", + feedback: Unselected, + }; + let form = [mk_typfun([[space(), _tp, space()]]), space(), _e]; + { + id: "typ_function_hole_id", + syntactic_form: form, + expandable_id: Some(Piece.id(_pat)), + explanation, + examples: [poly_id_ex], + }; +}; + +let typfunapp_exp_group = "typfunapp_exp_group"; +let typfunapp_exp_ex = { + sub_id: "typfunapp_exp_ex", + term: mk_example("(typfun X -> fun x : X \n -> x)@"), + message: "The polymorphic identity function instantiated at Int. Int is substituted in place of the type variable X in the body, so the body is effectively the identity function on integers.", + feedback: Unselected, +}; + +let _ty_fun = exp("ty_fun"); +let _ty_arg = typ("ty_arg"); +let typfunapp_exp_coloring_ids = + (~x_id: Id.t, ~arg_id: Id.t): list((Id.t, Id.t)) => [ + (Piece.id(_ty_fun), x_id), + (Piece.id(_ty_arg), arg_id), +]; +let typfunapp_exp: form = { + let explanation = { + message: "Type function application. Instantiate the [*polymorphic expression*](%s) at the [*argument type*](%s).", + feedback: Unselected, + }; + { + id: "typfunapp_exp", + syntactic_form: [_ty_fun, mk_tyap_exp([[_ty_arg]])], + expandable_id: None, + explanation, + examples: [typfunapp_exp_ex], + }; +}; + let tuple_exp_group = "tuple_exp_group"; let tuple_exp_2_group = "tuple_exp_2_group"; let tuple_exp_3_group = "tuple_exp_3_group"; @@ -3551,6 +3631,8 @@ let init = { function_tuple3_exp, function_ctr_exp, function_ap_exp, + typ_function_exp, + typ_function_hole, tuple_exp, tuple_exp_size2, tuple_exp_size3, @@ -3577,6 +3659,7 @@ let init = { tyalias_base_exp, funapp_exp, conapp_exp, + typfunapp_exp, if_exp, seq_exp, test_exp, @@ -3796,6 +3879,17 @@ let init = { ), ]), ), + ( + typ_function_group, + init_options([(typ_function_exp.id, [tpat("X")])]), + ), + ( + typ_function_hole_group, + init_options([ + (typ_function_exp.id, [tpat("X")]), + (typ_function_hole.id, [tpat("EmptyHole")]), + ]), + ), (tuple_exp_group, init_options([(tuple_exp.id, [])])), ( tuple_exp_2_group, @@ -3944,6 +4038,7 @@ let init = { (tyalias_exp_group, init_options([(tyalias_base_exp.id, [])])), (funapp_exp_group, init_options([(funapp_exp.id, [])])), (conapp_exp_group, init_options([(conapp_exp.id, [])])), + (typfunapp_exp_group, init_options([(typfunapp_exp.id, [])])), (if_exp_group, init_options([(if_exp.id, [])])), (seq_exp_group, init_options([(seq_exp.id, [])])), (test_group, init_options([(test_exp.id, [])])), diff --git a/src/haz3lweb/view/LangDoc.re b/src/haz3lweb/view/LangDoc.re index 79dfac0fe2..cd5cb814f1 100644 --- a/src/haz3lweb/view/LangDoc.re +++ b/src/haz3lweb/view/LangDoc.re @@ -672,20 +672,78 @@ let get_doc = ), [], ); - | TypFun(_, _) => - // TODO (typfun) - let (doc, options) = - LangDocMessages.get_form_and_options( - LangDocMessages.triv_exp_group, - docs, - ); - get_message( - doc, - options, - LangDocMessages.triv_exp_group, - doc.explanation.message, - [], - ); + | TypFun(_, _ /* tpat, body */) => + basic_info(LangDocMessages.typ_function_group) + /* TODO: Cannot quite get the below to work. The EmptyHole case throws an unhandled exception Not_found. + let basic = (doc: LangDocMessages.form, group_id, options) => { + let tpat_id = List.nth(tpat.ids, 0); + let body_id = List.nth(body.ids, 0); + get_message( + doc, + options, + group_id, + Printf.sprintf( + Scanf.format_from_string(doc.explanation.message, "%s%s"), + tpat_id |> Id.to_string, + body_id |> Id.to_string, + ), + LangDocMessages.typ_fun_pat_coloring_ids(~tpat_id, ~body_id), + ); + }; + switch (tpat.term) { + | EmptyHole => + let (doc, options) = + LangDocMessages.get_form_and_options( + LangDocMessages.typ_function_hole_group, + docs, + ); + if (LangDocMessages.typ_function_hole.id == doc.id) { + let tpat_id = List.nth(tpat.ids, 0); + let body_id = List.nth(body.ids, 0); + get_message( + doc, + options, + LangDocMessages.typ_function_hole_group, + Printf.sprintf( + Scanf.format_from_string(doc.explanation.message, "%s%s%s"), + tpat_id |> Id.to_string, + body_id |> Id.to_string, + tpat_id |> Id.to_string, + ), + LangDocMessages.typ_fun_hole_pat_coloring_ids( + ~tpat_id, + ~body_id, + ), + ); + } else { + basic(doc, LangDocMessages.typ_function_hole_group, options); + }; + | Var(var) => + let (doc, options) = + LangDocMessages.get_form_and_options( + LangDocMessages.typ_function_group, + docs, + ); + if (LangDocMessages.typ_function_exp.id == doc.id) { + let tpat_id = List.nth(tpat.ids, 0); + let body_id = List.nth(body.ids, 0); + get_message( + doc, + options, + LangDocMessages.typ_function_group, + Printf.sprintf( + Scanf.format_from_string(doc.explanation.message, "%s%s"), + var, + body_id |> Id.to_string, + ), + LangDocMessages.typ_fun_pat_coloring_ids(~tpat_id, ~body_id), + ); + } else { + basic(doc, LangDocMessages.typ_function_group, options); + }; + | _ => default + }; + */ | Fun(pat, body) => let basic = (doc: LangDocMessages.form, group_id, options) => { let pat_id = List.nth(pat.ids, 0); @@ -1921,20 +1979,8 @@ let get_doc = LangDocMessages.funapp_exp_coloring_ids, ); }; - | TypAp(_, _) => - // TODO (typfun) - let (doc, options) = - LangDocMessages.get_form_and_options( - LangDocMessages.triv_exp_group, - docs, - ); - get_message( - doc, - options, - LangDocMessages.triv_exp_group, - doc.explanation.message, - [], - ); + | TypAp(_, _) => basic_info(LangDocMessages.typfunapp_exp_group) + /* TODO: improve formating for TypAp? See TypFun. */ | If(cond, then_, else_) => let (doc, options) = LangDocMessages.get_form_and_options( From 3d85639288230745b69b0c2c0a544cc7b69c2a0a Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 14 Sep 2023 23:16:51 -0400 Subject: [PATCH 080/229] Keep original variable name in alpha rename. --- src/haz3lcore/statics/TypBase.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 79155f9bfd..d1ff9239a3 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -164,10 +164,10 @@ module rec Typ: { }; let var_count = ref(0); - let fresh_var = () => { + let fresh_var = (var_name: string) => { let x = var_count^; var_count := x + 1; - "@" ++ string_of_int(x); + var_name ++ "_α" ++ string_of_int(x); }; let rec subst = (s: t, x: TypVar.t, ty: t) => { From da33210b4e396231db8ea763aeab1605a0fef4bb Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Fri, 15 Sep 2023 19:24:20 -0400 Subject: [PATCH 081/229] Revised the description of inconsistency checking for list to Nil/Cons model. --- src/haz3lcore/dynamics/Incon.re | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 8b9bd7b02d..5732904d1f 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -185,10 +185,12 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => | (fs, other) => is_inconsistent(~may, other @ fs) } /* - * Thoughts for porting the Pair judgment to list: - * Two list constraints are automatically inconsistent if they have different length. - * So we first find maximum and minimum list lengths, and determine if they are the same. - * If so, we rearrange them in item-first order, and check each of them. + * Explanation for the check of inconsistency for list: + * List can be thought as the type (Nil(Unit) + Cons(Item, List)), or alternatively (Unit + (Item × List)). + * Thus by analogy with InjL and InjR, an empty list is inconsistent with a non-empty one, which means that two + * lists of different lengths are automatically inconsistent. If all lists are having the same length, then I + * will compare them from left to right (aka in the order of unfolding them) to see if any item in the same + * position are inconsistent. This version may be inefficient, but I am running out of ideas to optimize it. */ | List(_) => switch ( From 709f6d0d8bd0b3946b10548a6c4e7479b9bbbdbc Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 16 Sep 2023 21:05:41 -0400 Subject: [PATCH 082/229] Fix error in previous commit. --- src/haz3lcore/statics/TypBase.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index d1ff9239a3..8dc4162ee2 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -182,12 +182,12 @@ module rec Typ: { | Sum(sm) => Sum(ConstructorMap.map(Option.map(subst(s, x)), sm)) | Rec(y, ty) when TypVar.eq(x, y) => Rec(y, ty) | Rec(y, ty) when List.mem(y, free_vars(s)) => - let fresh = fresh_var(); + let fresh = fresh_var(y); Rec(fresh, subst(s, x, subst(Var(fresh), y, ty))); | Rec(y, ty) => Rec(y, subst(s, x, ty)) | Forall(y, ty) when TypVar.eq(x, y) => Forall(y, ty) | Forall(y, ty) when List.mem(y, free_vars(s)) => - let fresh = fresh_var(); + let fresh = fresh_var(y); Forall(fresh, subst(s, x, subst(Var(fresh), y, ty))); | Forall(y, ty) => Forall(y, subst(s, x, ty)) | List(ty) => List(subst(s, x, ty)) From 663b719954576f20cfe09928e59527e197e58f0a Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 16 Sep 2023 21:05:50 -0400 Subject: [PATCH 083/229] Return forall delimiter to -> from . --- src/haz3lcore/lang/Form.re | 4 ++-- src/haz3lcore/statics/MakeTerm.re | 6 +++--- src/haz3lweb/Init.ml | 12 ++++++------ src/haz3lweb/LangDocMessages.re | 4 ++-- src/haz3lweb/view/Type.re | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index 95be7b05d5..18f4c2061b 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -254,8 +254,8 @@ let forms: list((string, t)) = [ ("parens_typ", mk(ii, ["(", ")"], mk_op(Typ, [Typ]))), ("fun_", mk(ds, ["fun", "->"], mk_pre(P.fun_, Exp, [Pat]))), ("typfun", mk(ds, ["typfun", "->"], mk_pre(P.fun_, Exp, [TPat]))), - ("forall", mk(ds, ["forall", "."], mk_pre(P.fun_, Typ, [TPat]))), - ("rec", mk(ds, ["rec", "."], mk_pre(P.fun_, Typ, [TPat]))), + ("forall", mk(ds, ["forall", "->"], mk_pre(P.fun_, Typ, [TPat]))), + ("rec", mk(ds, ["rec", "->"], mk_pre(P.fun_, Typ, [TPat]))), ("if_", mk(ds, ["if", "then", "else"], mk_pre(P.if_, Exp, [Exp, Exp]))), ("ap_exp", mk(ii, ["(", ")"], mk_post(P.ap, Exp, [Exp]))), ("ap_pat", mk(ii, ["(", ")"], mk_post(P.ap, Pat, [Pat]))), diff --git a/src/haz3lcore/statics/MakeTerm.re b/src/haz3lcore/statics/MakeTerm.re index 778a6c4c3f..5c823f73b9 100644 --- a/src/haz3lcore/statics/MakeTerm.re +++ b/src/haz3lcore/statics/MakeTerm.re @@ -349,11 +349,11 @@ and typ_term: unsorted => (UTyp.term, list(Id.t)) = { | _ => ret(hole(tm)) } /* forall and rec have to be before sum so that they bind tighter. - * Thus `rec A . Left(A) + Right(B)` get parsed as `rec A . (Left(A) + Right(B))` + * Thus `rec A -> Left(A) + Right(B)` get parsed as `rec A -> (Left(A) + Right(B))` * If this is below the case for sum, then it gets parsed as an invalid form. */ - | Pre(([(_id, (["forall", "."], [TPat(tpat)]))], []), Typ(t)) => + | Pre(([(_id, (["forall", "->"], [TPat(tpat)]))], []), Typ(t)) => ret(Forall(tpat, t)) - | Pre(([(_id, (["rec", "."], [TPat(tpat)]))], []), Typ(t)) => + | Pre(([(_id, (["rec", "->"], [TPat(tpat)]))], []), Typ(t)) => ret(Rec(tpat, t)) | Pre(tiles, Typ({term: Sum(t0), ids})) as tm => /* Case for leading prefix + preceeding a sum */ diff --git a/src/haz3lweb/Init.ml b/src/haz3lweb/Init.ml index 49e8145694..5cdc5122b1 100644 --- a/src/haz3lweb/Init.ml +++ b/src/haz3lweb/Init.ml @@ -15013,21 +15013,21 @@ let startup : PersistentData.t = # Such functions are applied like so: #\n\ let ex1 = id@(1) in # 1 #\n\n\ # We can annotate the type of a type function with a forall. #\n\ - let const : forall A . forall B . A -> B -> A = \n\ + let const : forall A -> forall B -> A -> B -> A = \n\ typfun A -> typfun B -> fun x -> fun y -> x in\n\ let ex2 = const@@(2)(\"Hello World\") in # 2 #\n\n\ # We can go beyond rank 1 polymorphism: #\n\ - let apply_both : forall A . forall B . (forall D . D -> D) -> \ - (A , B) -> (A , B) =\n\ + let apply_both : forall A -> forall B -> (forall D -> D -> D) \ + -> (A , B) -> (A , B) =\n\ typfun A -> typfun B -> fun f -> fun (x, y) -> (f@(x), \ f@(y)) in \n\ let ex3 = apply_both@@(id)(3, \"Hello World\") \ in # (3, \"Hello World\") # \n\n\ # Finally, here is a more in-depth, yet applicable example: \ polymorphic map #\n\ - let emptylist : forall A . [A] = typfun A -> [] in # \ + let emptylist : forall A -> [A] = typfun A -> [] in # \ polymorphic constant #\n\ - let map : forall A . forall B . (A -> B) -> ([A] -> [B]) = \n\ + let map : forall A -> forall B -> (A -> B) -> ([A] -> [B]) = \n\ typfun A -> typfun B -> fun f : (A -> B) -> fun l : [A] -> \n\ case l\n\ | h :: t => f(h) :: map@@(f)(t)\n\ @@ -15038,7 +15038,7 @@ let startup : PersistentData.t = # Recursive types #\n\n\ # We can express types that are the least fixed point of #\n\ # some type function with the rec keyword. #\n\ - type MyList = rec A. (Nil + Cons(Int, A)) in\n\n\ + type MyList = rec A -> (Nil + Cons(Int, A)) in\n\n\ # Hazel does not (yet) support higher-kinded or existential \ types, #\n\ # So we cannot implement our own polymorphic lists. #\n\n\ diff --git a/src/haz3lweb/LangDocMessages.re b/src/haz3lweb/LangDocMessages.re index 02920127dc..b29f2bd625 100644 --- a/src/haz3lweb/LangDocMessages.re +++ b/src/haz3lweb/LangDocMessages.re @@ -379,14 +379,14 @@ let poly_id_ex = { sub_id: "poly_id_ex", term: mk_example( - "let id : \n forall X . (X -> X) = \n typfun X -> \n fun x : X -> x \n in id", + "let id : \n forall X -> (X -> X) = \n typfun X -> \n fun x : X -> x \n in id", ), message: "The polymorphic identity function. It may be instantiated at any type X, after which the function acts as type (X -> X).", feedback: Unselected, }; let peano_ex = { sub_id: "peano_ex", - term: mk_example("type Peano = \n rec P . Z + S(P) \n in S(S(S(Z)))"), + term: mk_example("type Peano = \n rec P -> Z + S(P) \n in S(S(S(Z)))"), message: "The type of the Peano numbers and the representation of the number 3.", feedback: Unselected, }; diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index 6e53ae5834..be05cfdae2 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -53,12 +53,12 @@ let rec view_ty = (~strip_outer_parens=false, ty: Haz3lcore.Typ.t): Node.t => | Rec(name, t) => div( ~attr=clss(["typ-view", "Rec"]), - [text("rec " ++ name ++ ". "), ...paren_view(t)], + [text("rec " ++ name ++ " -> "), ...ty_view(t)], ) | Forall(name, t) => div( ~attr=clss(["typ-view", "Forall"]), - [text("forall " ++ name ++ ". "), ...paren_view(t)], + [text("forall " ++ name ++ " -> "), ...ty_view(t)], ) | List(t) => div( From f8da1dc94c090479976dfb3f50fe2eea4594ad18 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 16 Sep 2023 21:10:38 -0400 Subject: [PATCH 084/229] Fix error. --- src/haz3lweb/view/Type.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index be05cfdae2..eb0f198d38 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -53,12 +53,12 @@ let rec view_ty = (~strip_outer_parens=false, ty: Haz3lcore.Typ.t): Node.t => | Rec(name, t) => div( ~attr=clss(["typ-view", "Rec"]), - [text("rec " ++ name ++ " -> "), ...ty_view(t)], + [text("rec " ++ name ++ " -> "), view_ty(t)], ) | Forall(name, t) => div( ~attr=clss(["typ-view", "Forall"]), - [text("forall " ++ name ++ " -> "), ...ty_view(t)], + [text("forall " ++ name ++ " -> "), view_ty(t)], ) | List(t) => div( From a19bc2f8141262be83146155df200fae6a1cbf4c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 20 Sep 2023 18:31:50 -0400 Subject: [PATCH 085/229] Init --- src/haz3lcore/statics/Statics.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index f5962cce77..2878b18f04 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -283,6 +283,7 @@ and uexp_to_info_map = es, p_ctxs, ); + let rec ruls_to_info_map = (xi_pre: Constraint.t, m) => (xi_pre, m); let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); From e0fbe8da05619ecc0263d05b6d9a642c04ef65f6 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sat, 23 Sep 2023 21:49:07 -0400 Subject: [PATCH 086/229] Return `Constraint.re` and `Incon.re` to their old version. --- src/haz3lcore/dynamics/Constraint.re | 48 ++++++++++--------------- src/haz3lcore/dynamics/Incon.re | 53 +++++++--------------------- 2 files changed, 31 insertions(+), 70 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 0a4b705a2d..21cb280ad3 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -15,9 +15,8 @@ type t = | Or(t, t) | InjL(t) | InjR(t) - | List(list(t)); + | Pair(t, t); -// How to replace this function? let rec constrains = (c: t, ty: Typ.t): bool => switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { | (Truth, _) @@ -45,15 +44,7 @@ let rec constrains = (c: t, ty: Typ.t): bool => | map' => constrains(c2, Sum(map')) } | (InjR(_), _) => false - | (List(c), ty) => - List.fold_left((last, x) => last && constrains(x, ty), true, c) - }; - -let rec or_constraints = (lst: list(t)): t => - switch (lst) { - | [] => failwith("should have at least one constraint") - | [xi] => xi - | [xi, ...xis] => Or(xi, or_constraints(xis)) + | (Pair(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) }; let rec dual = (c: t): t => @@ -71,19 +62,11 @@ let rec dual = (c: t): t => | Or(c1, c2) => And(dual(c1), dual(c2)) | InjL(c1) => Or(InjL(dual(c1)), InjR(Truth)) | InjR(c2) => Or(InjR(dual(c2)), InjL(Truth)) - // Thought: generate all combinations of ways to dual the list (2^n - 1), and connect them with or - | List(l) => - let permutation = List.map(l' => List(l'), List.tl(permutate(l))); - // ``Or'' is associative, so I try to use this way to simplify it - or_constraints(permutation); - } -and permutate = (l: list(t)): list(list(t)) => - switch (l) { - | [] => [[]] - | [hd, ...tl] => - let result_tl = permutate(tl); - List.map(l' => [hd, ...l'], result_tl) - @ List.map(l' => [dual(hd), ...l'], result_tl); + | Pair(c1, c2) => + Or( + Pair(c1, dual(c2)), + Or(Pair(dual(c1), c2), Pair(dual(c1), dual(c2))), + ) }; /** substitute Truth for Hole */ @@ -102,7 +85,7 @@ let rec truify = (c: t): t => | Or(c1, c2) => Or(truify(c1), truify(c2)) | InjL(c) => InjL(truify(c)) | InjR(c) => InjR(truify(c)) - | List(l) => List(List.map(c => truify(c), l)) + | Pair(c1, c2) => Pair(truify(c1), truify(c2)) }; /** substitute Falsity for Hole */ @@ -121,7 +104,7 @@ let rec falsify = (c: t): t => | Or(c1, c2) => Or(falsify(c1), falsify(c2)) | InjL(c) => InjL(falsify(c)) | InjR(c) => InjR(falsify(c)) - | List(l) => List(List.map(c => falsify(c), l)) + | Pair(c1, c2) => Pair(falsify(c1), falsify(c2)) }; let unwrapL = @@ -134,7 +117,14 @@ let unwrapR = | InjR(c) => c | _ => failwith("input can only be InjR(_)"); -let unwrap_list = +let unwrap_pair = fun - | List(l) => l - | _ => failwith("input can only be List([_, ..._])"); + | Pair(c1, c2) => (c1, c2) + | _ => failwith("input can only be pair(_, _)"); + +let rec or_constraints = (lst: list(t)): t => + switch (lst) { + | [] => failwith("should have at least one constraint") + | [xi] => xi + | [xi, ...xis] => Or(xi, or_constraints(xis)) + }; diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 5732904d1f..5d41604928 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -184,56 +184,27 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => | (fs, []) => is_inconsistent_string(fs) | (fs, other) => is_inconsistent(~may, other @ fs) } - /* - * Explanation for the check of inconsistency for list: - * List can be thought as the type (Nil(Unit) + Cons(Item, List)), or alternatively (Unit + (Item × List)). - * Thus by analogy with InjL and InjR, an empty list is inconsistent with a non-empty one, which means that two - * lists of different lengths are automatically inconsistent. If all lists are having the same length, then I - * will compare them from left to right (aka in the order of unfolding them) to see if any item in the same - * position are inconsistent. This version may be inefficient, but I am running out of ideas to optimize it. - */ - | List(_) => + | Pair(_, _) => switch ( List.partition( fun - | Constraint.List(_) => true + | Constraint.Pair(_) => true | _ => false, xis, ) ) { - | (lists, []) => - let lengths = - List.map(x => List.length(Constraint.unwrap_list(x)), lists); - // check if all lengths are equal - // This could be done with exceptions, but I found nothing related on ReasonML website. - let all_lengths_are_equal = - List.for_all(x => x == List.hd(lengths), List.tl(lengths)); - if (all_lengths_are_equal) { - let order_by_index = - List.fold_left( - // ordered_by_index: list(list(t)); item: packed version of list(t) - (ordered_by_index, lst) => - List.map2( - // We need a function that maps `(list(t), t)` to list(list(t) - (old_list, item) => [item, ...old_list], - ordered_by_index, - Constraint.unwrap_list(lst), - ), - // Initial version of empty list, in list(list(t)) - List.map(x => [x], Constraint.unwrap_list(List.hd(lists))), - // Rest of items - List.tl(lists), - ); - // Check if there are inconsistency in each element + | (pairs, []) => + let (xisL, xisR) = List.fold_left( - (previous, item) => previous || is_inconsistent(~may, item), - may, - order_by_index, + ((xisL, xisR), pair) => { + let (xiL, xiR) = Constraint.unwrap_pair(pair); + ([xiL, ...xisL], [xiR, ...xisR]); + }, + ([], []), + pairs, ); - } else { - true; // Automatically inconsistent - }; - | (lists, other) => is_inconsistent(~may, other @ lists) + is_inconsistent(~may, xisL) || is_inconsistent(~may, xisR); + | (pairs, other) => is_inconsistent(~may, other @ pairs) } } }; From 3f00366bd7380b9adbe1181ace1c2b89c5388d71 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 26 Sep 2023 14:32:05 -0400 Subject: [PATCH 087/229] Fix error in syntactix translation of types and address review comments. --- src/haz3lcore/statics/Info.re | 4 ++-- src/haz3lcore/statics/Kind.re | 1 + src/haz3lcore/statics/Mode.re | 9 +++++---- src/haz3lcore/statics/Statics.re | 8 ++++++-- src/haz3lcore/statics/Term.re | 13 ++++++------- src/haz3lcore/statics/TypBase.re | 24 ++++++++++++++---------- 6 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 src/haz3lcore/statics/Kind.re diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index ec45060d40..59bb8d4be9 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -276,7 +276,7 @@ let rec status_common = } | (Just(ty), SynTypFun) => /* Use ty first to preserve name if it exists. */ - switch (Typ.join_fix(ctx, ty, Forall("_", Unknown(Internal)))) { + switch (Typ.join_fix(ctx, ty, Forall("?", Unknown(Internal)))) { | Some(_) => NotInHole(Syn(ty)) | None => InHole(Inconsistent(WithArrow(ty))) } @@ -366,7 +366,7 @@ let status_typ = | TypeExpected => switch (Ctx.is_alias(ctx, name)) { | false => - switch (Ctx.is_tvar(ctx, name)) { + switch (Ctx.is_abstract(ctx, name)) { | false => InHole(FreeTypeVariable(name)) | true => NotInHole(Type(Var(name))) } diff --git a/src/haz3lcore/statics/Kind.re b/src/haz3lcore/statics/Kind.re new file mode 100644 index 0000000000..8db5638e94 --- /dev/null +++ b/src/haz3lcore/statics/Kind.re @@ -0,0 +1 @@ +include TypBase.Kind; diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index ed4ad1978d..adb48881fd 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -48,10 +48,11 @@ let of_forall = (ctx: Ctx.t, name_opt: option(TypVar.t), mode: t): t => | SynFun | SynTypFun => Syn | Ana(ty) => - let (name_expected, item) = Typ.matched_forall(ctx, ty); - switch (name_opt) { - | Some(name) => Ana(Typ.subst(Var(name), name_expected, item)) - | None => Ana(item) + let (name_expected_opt, item) = Typ.matched_forall(ctx, ty); + switch (name_opt, name_expected_opt) { + | (Some(name), Some(name_expected)) => + Ana(Typ.subst(Var(name), name_expected, item)) + | _ => Ana(item) }; }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6d1006b7b6..dfe0214dc3 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -239,9 +239,13 @@ and uexp_to_info_map = | TypAp(fn, utyp) => let typfn_mode = Mode.typap_mode; let (fn, m_fn) = go(~mode=typfn_mode, fn, m); - let (name, ty_body) = Typ.matched_forall(ctx, fn.ty); + let (option_name, ty_body) = Typ.matched_forall(ctx, fn.ty); let ty = Term.UTyp.to_typ(ctx, utyp); - add(~self=Just(Typ.subst(ty, name, ty_body)), ~co_ctx=fn.co_ctx, m_fn); + switch (option_name) { + | Some(name) => + add(~self=Just(Typ.subst(ty, name, ty_body)), ~co_ctx=fn.co_ctx, m_fn) + | None => add(~self=Just(ty_body), ~co_ctx=fn.co_ctx, m_fn) /* invalid name matches with no free type variables. */ + }; | Fun(p, e) => let (mode_pat, mode_body) = Mode.of_arrow(ctx, mode); let (p, m) = go_pat(~is_synswitch=false, ~mode=mode_pat, p, m); diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 90f1d1a7f6..1294eb55c7 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -207,8 +207,7 @@ module UTyp = { {name, id: UTPat.rep_id(utpat), kind: Abstract}, ); Forall(name, to_typ(ctx, tbody)); - | Forall(_, tbody) => to_typ(ctx, tbody) - // Forall is same as Rec + // Rec is same as Forall | Rec({term: Var(name), _} as utpat, tbody) => let ctx = Ctx.extend_tvar( @@ -216,7 +215,8 @@ module UTyp = { {name, id: UTPat.rep_id(utpat), kind: Abstract}, ); Rec(name, to_typ(ctx, tbody)); - | Rec(_, tbody) => to_typ(ctx, tbody) + | Forall(_, tbody) => Forall("?", to_typ(ctx, tbody)) + | Rec(_, tbody) => Rec("?", to_typ(ctx, tbody)) /* The below cases should occur only inside sums */ | Constructor(_) | Ap(_) => Unknown(Internal) @@ -620,7 +620,7 @@ module UExp = { | Let => "Let expression" | TyAlias => "Type Alias definition" | Ap => "Application" - | TypAp => "Type Application" + | TypAp => "Type application" | If => "If expression" | Seq => "Sequence expression" | Test => "Test" @@ -631,9 +631,8 @@ module UExp = { | UnOp(op) => show_unop(op) | Match => "Case expression"; - // TODO (poly): May need to create a separate is_typfun function, - // so that is_fun pairs with is_fun_var over Arrow - // and is_typfun pairs with is_typfun_var over Forall + // Typfun should be treated as a function here as this is only used to + // determine when to allow for recursive definitions in a let binding. let rec is_fun = (e: t) => { switch (e.term) { | Parens(e) => is_fun(e) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 8dc4162ee2..2d158051dc 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -53,7 +53,7 @@ module rec Typ: { let join_type_provenance: (type_provenance, type_provenance) => type_provenance; let matched_arrow: (Ctx.t, t) => (t, t); - let matched_forall: (Ctx.t, t) => (string, t); + let matched_forall: (Ctx.t, t) => (option(string), t); let matched_prod: (Ctx.t, int, t) => list(t); let matched_list: (Ctx.t, t) => t; let precedence: t => int; @@ -160,7 +160,6 @@ module rec Typ: { | Prod(tys) => ListUtil.flat_map(free_vars(~bound), tys) | Rec(x, ty) => free_vars(~bound=[x, ...bound], ty) | Forall(x, ty) => free_vars(~bound=[x, ...bound], ty) - /* TODO: check that these are correct. */ }; let var_count = ref(0); @@ -201,8 +200,8 @@ module rec Typ: { | _ => ty }; - /* Type Equality: At the moment, this coincides with alpha equivalence, - but this will change when polymorphic types are implemented */ + /* Type Equality: This coincides with alpha equivalence for normalized types. + Other types may be equivalent but this will not detect so if they are not normalized. */ let rec eq_internal = (n: int, t1: t, t2: t) => { switch (t1, t2) { | (Rec(x1, t1), Rec(x2, t2)) @@ -232,6 +231,7 @@ module rec Typ: { | (List(t1), List(t2)) => eq_internal(n, t1, t2) | (List(_), _) => false | (Sum(sm1), Sum(sm2)) => + /* Does not normalize the types. */ ConstructorMap.equal(Option.equal(eq_internal(n)), sm1, sm2) | (Sum(_), _) => false | (Var(n1), Var(n2)) => n1 == n2 @@ -284,6 +284,10 @@ module rec Typ: { let+ ty_body = join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); Forall(x1, ty_body); + /* Note for above: there is no danger of free variable capture as + subst itself performs capture avoiding substitution. However this + may generate internal type variable names that in corner cases can + be exposed to the user. */ | (Rec(_), _) => None | (Forall(_), _) => None | (Int, Int) => Some(Int) @@ -399,9 +403,9 @@ module rec Typ: { let matched_forall = (ctx, ty) => switch (weak_head_normalize(ctx, ty)) { - | Forall(t, ty) => (t, ty) - | Unknown(SynSwitch) => ("matched_forall", Unknown(SynSwitch)) - | _ => ("matched_forall", Unknown(Internal)) /* TODO: Might need to be fresh? */ + | Forall(t, ty) => (Some(t), ty) + | Unknown(SynSwitch) => (None, Unknown(SynSwitch)) + | _ => (None, Unknown(Internal)) }; let matched_prod = (ctx, length, ty) => @@ -482,7 +486,7 @@ and Ctx: { let lookup_var: (t, string) => option(var_entry); let lookup_ctr: (t, string) => option(var_entry); let is_alias: (t, TypVar.t) => bool; - let is_tvar: (t, TypVar.t) => bool; + let is_abstract: (t, TypVar.t) => bool; let add_ctrs: (t, TypVar.t, Id.t, Typ.sum_map) => t; let subtract_prefix: (t, t) => option(t); let added_bindings: (t, t) => t; @@ -566,7 +570,7 @@ and Ctx: { | None => false }; - let is_tvar = (ctx: t, name: TypVar.t): bool => + let is_abstract = (ctx: t, name: TypVar.t): bool => switch (lookup_tvar(ctx, name)) { | Some({kind: Abstract, _}) => true | _ => false @@ -636,7 +640,7 @@ and Ctx: { |> (((ctx, _, _)) => List.rev(ctx)); let shadows_typ = (ctx: t, name: TypVar.t): bool => - Form.is_base_typ(name) || is_alias(ctx, name) || is_tvar(ctx, name); + Form.is_base_typ(name) || is_alias(ctx, name) || is_abstract(ctx, name); } and Kind: { [@deriving (show({with_path: false}), sexp, yojson)] From 1022c550dab82613922b411fd5a0750bc3813da7 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 12:58:24 -0400 Subject: [PATCH 088/229] Initialized error_exp.InexhaustiveMatch --- src/haz3lcore/statics/Info.re | 1 + src/haz3lcore/statics/Statics.re | 2 +- src/haz3lweb/view/CursorInspector.re | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 69d3871db6..7fcc9b16d8 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -64,6 +64,7 @@ type error_common = [@deriving (show({with_path: false}), sexp, yojson)] type error_exp = | FreeVariable(Var.t) /* Unbound variable (not in typing context) */ + | InexhaustiveMatch(option(error_common)) /* Inexhaustive match (optional inconsistent types error) */ | Common(error_common); [@deriving (show({with_path: false}), sexp, yojson)] diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 9aa4142d94..2da2ca6bb4 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -283,7 +283,7 @@ and uexp_to_info_map = es, p_ctxs, ); - let rec ruls_to_info_map = (xi_pre: Constraint.t, m) => (xi_pre, m); + // let rec ruls_to_info_map = (xi_pre: Constraint.t, m) => (xi_pre, m); let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 821e92a48a..86070d4ed0 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -161,6 +161,16 @@ let exp_view = (cls: Term.Cls.t, status: Info.status_exp) => switch (status) { | InHole(FreeVariable(name)) => div_err([code_err(name), text("not found")]) + | InHole(InexhaustiveMatch(type_err)) => + let inexhaustive_err_text = "Case expression is necessarily inexhaustive"; + switch (type_err) { + | None => div_err([text(inexhaustive_err_text)]) + | Some(type_err) => + div_err([ + text(inexhaustive_err_text ++ "; "), + ...common_err_view(Exp(Match), type_err), + ]) + }; | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; From 70996ad1a13366406f17c55faf3b40e9469c19f8 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 14:46:21 -0400 Subject: [PATCH 089/229] Add a new reason to have DHExp.InconsistentBranches in elaborator --- src/haz3lcore/dynamics/Elaborator.re | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 47e2d484c2..e9b433b629 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -267,7 +267,8 @@ let rec dhexp_of_uexp = |> OptUtil.sequence; let d = DHExp.Case(d_scrut, d_rules, 0); switch (err_status) { - | InHole(Common(Inconsistent(Internal(_)))) => + | InHole(Common(Inconsistent(Internal(_)))) + | InHole(InexhaustiveMatch(Some(Inconsistent(Internal(_))))) => DHExp.InconsistentBranches(id, 0, d) | _ => ConsistentCase(d) }; From e179d767dfdefa3451d8a426bc5792d5bef75062 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 14:49:30 -0400 Subject: [PATCH 090/229] Initialized Self.exp.InexhaustiveMatch --- src/haz3lcore/statics/Self.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re index f30c1e2e13..73be27fc01 100644 --- a/src/haz3lcore/statics/Self.re +++ b/src/haz3lcore/statics/Self.re @@ -35,6 +35,7 @@ type t = [@deriving (show({with_path: false}), sexp, yojson)] type exp = | Free(Var.t) + | InexhaustiveMatch(t) | Common(t); [@deriving (show({with_path: false}), sexp, yojson)] From f0b9fef18945b0a99e4d8c4bb1ed8592d62572a3 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 15:42:57 -0400 Subject: [PATCH 091/229] Added more guards & updated Info.status_exp --- src/haz3lcore/statics/Info.re | 9 +++++++++ src/haz3lweb/view/CursorInspector.re | 12 ++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 7fcc9b16d8..8705e6c221 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -322,6 +322,15 @@ let status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => switch (self, mode) { | (Free(name), _) => InHole(FreeVariable(name)) + | (InexhaustiveMatch(self_pat), _) => + let inconsistent_err = + switch (status_common(ctx, mode, self_pat)) { + | NotInHole(_) => None + | InHole(Inconsistent(Internal(_)) as inconsistent_err) => + Some(inconsistent_err) + | _ => failwith("InexhaustiveMatch(non-inconsistent-types-error)") + }; + InexhaustiveMatch(inconsistent_err); | (Common(self_pat), _) => switch (status_common(ctx, mode, self_pat)) { | NotInHole(ok_exp) => NotInHole(ok_exp) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 86070d4ed0..1809245f22 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -161,15 +161,19 @@ let exp_view = (cls: Term.Cls.t, status: Info.status_exp) => switch (status) { | InHole(FreeVariable(name)) => div_err([code_err(name), text("not found")]) - | InHole(InexhaustiveMatch(type_err)) => + | InHole(InexhaustiveMatch(inconsistent_err)) => let inexhaustive_err_text = "Case expression is necessarily inexhaustive"; - switch (type_err) { + switch (inconsistent_err) { | None => div_err([text(inexhaustive_err_text)]) - | Some(type_err) => + | Some(Inconsistent(Internal(_)) as inconsistent_err) => div_err([ text(inexhaustive_err_text ++ "; "), - ...common_err_view(Exp(Match), type_err), + ...common_err_view(Exp(Match), inconsistent_err), ]) + | _ => + failwith( + "Case expression is necessarily inexhaustive; non-inconsistent-types-error", + ) }; | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) From b66c0ccf18e90a3dbc65922d63d62fa37cadee5a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 15:54:24 -0400 Subject: [PATCH 092/229] Complete new self --- src/haz3lcore/statics/Info.re | 2 +- src/haz3lcore/statics/Self.re | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 8705e6c221..c8e3f456d5 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -330,7 +330,7 @@ let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => Some(inconsistent_err) | _ => failwith("InexhaustiveMatch(non-inconsistent-types-error)") }; - InexhaustiveMatch(inconsistent_err); + InHole(InexhaustiveMatch(inconsistent_err)); | (Common(self_pat), _) => switch (status_common(ctx, mode, self_pat)) { | NotInHole(ok_exp) => NotInHole(ok_exp) diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re index 73be27fc01..500ab0d89b 100644 --- a/src/haz3lcore/statics/Self.re +++ b/src/haz3lcore/statics/Self.re @@ -57,7 +57,8 @@ let typ_of: (Ctx.t, t) => option(Typ.t) = let typ_of_exp: (Ctx.t, exp) => option(Typ.t) = ctx => fun - | Free(_) => None + | Free(_) + | InexhaustiveMatch(_) => None | Common(self) => typ_of(ctx, self); let typ_of_pat: (Ctx.t, pat) => option(Typ.t) = From f8ff3c45caac7404a22006783c243493da2691da Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 16:43:05 -0400 Subject: [PATCH 093/229] Fixed the bug about type inconsistency --- src/haz3lcore/statics/Info.re | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index c8e3f456d5..ec068a44ca 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -325,10 +325,11 @@ let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => | (InexhaustiveMatch(self_pat), _) => let inconsistent_err = switch (status_common(ctx, mode, self_pat)) { - | NotInHole(_) => None | InHole(Inconsistent(Internal(_)) as inconsistent_err) => Some(inconsistent_err) - | _ => failwith("InexhaustiveMatch(non-inconsistent-types-error)") + | NotInHole(_) + | InHole(Inconsistent(Expectation(_) | WithArrow(_))) => None /* Type checking should fail */ + | InHole(NoType(_)) => failwith("InHole(InexhaustiveMatch(impossible_err))") }; InHole(InexhaustiveMatch(inconsistent_err)); | (Common(self_pat), _) => From bf4c052895dd4ae507b37b028c4765778845ac76 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 27 Sep 2023 16:44:47 -0400 Subject: [PATCH 094/229] Formatted --- src/haz3lcore/statics/Info.re | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index ec068a44ca..a770863dab 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -329,7 +329,8 @@ let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => Some(inconsistent_err) | NotInHole(_) | InHole(Inconsistent(Expectation(_) | WithArrow(_))) => None /* Type checking should fail */ - | InHole(NoType(_)) => failwith("InHole(InexhaustiveMatch(impossible_err))") + | InHole(NoType(_)) => + failwith("InHole(InexhaustiveMatch(impossible_err))") }; InHole(InexhaustiveMatch(inconsistent_err)); | (Common(self_pat), _) => From 213ad9648e35e26229d50634e5039bcef0b6fc2a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 09:15:02 -0400 Subject: [PATCH 095/229] Made InexhaustiveMatch more general --- src/haz3lcore/statics/Info.re | 13 +++++++------ src/haz3lcore/statics/Self.re | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index a770863dab..1480f3b154 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -319,17 +319,18 @@ let status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => depending on the mode, which represents the expectations of the surrounding syntactic context, and the self which represents the makeup of the expression / pattern itself. */ -let status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => +let rec status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => switch (self, mode) { | (Free(name), _) => InHole(FreeVariable(name)) - | (InexhaustiveMatch(self_pat), _) => + | (InexhaustiveMatch(self), _) => let inconsistent_err = - switch (status_common(ctx, mode, self_pat)) { - | InHole(Inconsistent(Internal(_)) as inconsistent_err) => + switch (status_exp(ctx, mode, self)) { + | InHole(Common(Inconsistent(Internal(_)) as inconsistent_err)) => Some(inconsistent_err) | NotInHole(_) - | InHole(Inconsistent(Expectation(_) | WithArrow(_))) => None /* Type checking should fail */ - | InHole(NoType(_)) => + | InHole(Common(Inconsistent(Expectation(_) | WithArrow(_)))) => None /* Type checking should fail */ + | InHole(Common(NoType(_))) + | InHole(FreeVariable(_) | InexhaustiveMatch(_)) => failwith("InHole(InexhaustiveMatch(impossible_err))") }; InHole(InexhaustiveMatch(inconsistent_err)); diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re index 500ab0d89b..684b19b01b 100644 --- a/src/haz3lcore/statics/Self.re +++ b/src/haz3lcore/statics/Self.re @@ -35,7 +35,7 @@ type t = [@deriving (show({with_path: false}), sexp, yojson)] type exp = | Free(Var.t) - | InexhaustiveMatch(t) + | InexhaustiveMatch(exp) | Common(t); [@deriving (show({with_path: false}), sexp, yojson)] From c226608633887c2f47db6eb4515eb045735d5a66 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 09:32:35 -0400 Subject: [PATCH 096/229] Making InexhaustiveMatch even more general! --- src/haz3lcore/dynamics/Elaborator.re | 4 +++- src/haz3lcore/statics/Info.re | 10 +++++----- src/haz3lweb/view/CursorInspector.re | 14 +++++--------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index e9b433b629..126dee2e21 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -268,7 +268,9 @@ let rec dhexp_of_uexp = let d = DHExp.Case(d_scrut, d_rules, 0); switch (err_status) { | InHole(Common(Inconsistent(Internal(_)))) - | InHole(InexhaustiveMatch(Some(Inconsistent(Internal(_))))) => + | InHole( + InexhaustiveMatch(Some(Common(Inconsistent(Internal(_))))), + ) => DHExp.InconsistentBranches(id, 0, d) | _ => ConsistentCase(d) }; diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 1480f3b154..57d9f71b4e 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -64,7 +64,7 @@ type error_common = [@deriving (show({with_path: false}), sexp, yojson)] type error_exp = | FreeVariable(Var.t) /* Unbound variable (not in typing context) */ - | InexhaustiveMatch(option(error_common)) /* Inexhaustive match (optional inconsistent types error) */ + | InexhaustiveMatch(option(error_exp)) | Common(error_common); [@deriving (show({with_path: false}), sexp, yojson)] @@ -323,17 +323,17 @@ let rec status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => switch (self, mode) { | (Free(name), _) => InHole(FreeVariable(name)) | (InexhaustiveMatch(self), _) => - let inconsistent_err = + let additional_err = switch (status_exp(ctx, mode, self)) { - | InHole(Common(Inconsistent(Internal(_)) as inconsistent_err)) => + | InHole(Common(Inconsistent(Internal(_))) as inconsistent_err) => Some(inconsistent_err) | NotInHole(_) - | InHole(Common(Inconsistent(Expectation(_) | WithArrow(_)))) => None /* Type checking should fail */ + | InHole(Common(Inconsistent(Expectation(_) | WithArrow(_)))) => None /* Type checking should fail and these errors would be nullified */ | InHole(Common(NoType(_))) | InHole(FreeVariable(_) | InexhaustiveMatch(_)) => failwith("InHole(InexhaustiveMatch(impossible_err))") }; - InHole(InexhaustiveMatch(inconsistent_err)); + InHole(InexhaustiveMatch(additional_err)); | (Common(self_pat), _) => switch (status_common(ctx, mode, self_pat)) { | NotInHole(ok_exp) => NotInHole(ok_exp) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 1809245f22..9576602b41 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -157,23 +157,19 @@ let typ_err_view = (ok: Info.error_typ) => ] }; -let exp_view = (cls: Term.Cls.t, status: Info.status_exp) => +let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => switch (status) { | InHole(FreeVariable(name)) => div_err([code_err(name), text("not found")]) - | InHole(InexhaustiveMatch(inconsistent_err)) => + | InHole(InexhaustiveMatch(additional_err)) => let inexhaustive_err_text = "Case expression is necessarily inexhaustive"; - switch (inconsistent_err) { + switch (additional_err) { | None => div_err([text(inexhaustive_err_text)]) - | Some(Inconsistent(Internal(_)) as inconsistent_err) => + | Some(err) => div_err([ text(inexhaustive_err_text ++ "; "), - ...common_err_view(Exp(Match), inconsistent_err), + exp_view(Exp(Match), InHole(err)), ]) - | _ => - failwith( - "Case expression is necessarily inexhaustive; non-inconsistent-types-error", - ) }; | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) From 74b947a125b48ccd7fb9faf28aece4f3282a18bb Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 09:40:32 -0400 Subject: [PATCH 097/229] Test --- src/haz3lcore/statics/Statics.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2da2ca6bb4..70b92567ce 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -287,8 +287,8 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - add( - ~self=Self.match(ctx, e_tys, branch_ids), + add'( + ~self=InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))), ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m, ); From bbc8406e90642933d4abbb9370d79a04375ef833 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 09:48:26 -0400 Subject: [PATCH 098/229] Make it less akaward --- src/haz3lweb/view/CursorInspector.re | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 9576602b41..6cc2adf8f6 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -162,15 +162,14 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => | InHole(FreeVariable(name)) => div_err([code_err(name), text("not found")]) | InHole(InexhaustiveMatch(additional_err)) => - let inexhaustive_err_text = "Case expression is necessarily inexhaustive"; switch (additional_err) { - | None => div_err([text(inexhaustive_err_text)]) + | None => div_err([text("Case expression is necessarily inexhaustive")]) | Some(err) => div_err([ - text(inexhaustive_err_text ++ "; "), exp_view(Exp(Match), InHole(err)), + text("; case expression is necessarily inexhaustive"), ]) - }; + } | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; From 56d33fd0abf9c79fddcc67cd2004d0dabd720149 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 10:21:47 -0400 Subject: [PATCH 099/229] Revert Id.re --- src/haz3lcore/tiles/Id.re | 67 --------------------------------------- 1 file changed, 67 deletions(-) diff --git a/src/haz3lcore/tiles/Id.re b/src/haz3lcore/tiles/Id.re index 00fcb693b7..29205c49e6 100644 --- a/src/haz3lcore/tiles/Id.re +++ b/src/haz3lcore/tiles/Id.re @@ -32,73 +32,6 @@ */ -/* ID FAQ - - WHAT ARE IDS USED FOR? - - Unique ids are assigned to tiles (and hence, indirectly, to terms) - at the time of creation of surface syntax. Ids are used as keys in - various maps (mostly notably the Measured map, which tracks screen - coordinates for the view, and the Info map which collects static - data such as type information). - - BUT WHY IS THERE A _LIST_ OF IDS? - - Technically, each tile has a list of ids, to support n-ary forms like - tuples; there are rep_id functions in Term to canonically extract - single representative ids from this list where appropriate. - - HOW ARE NEW IDS CREATED? - - In the parts of the implementation which manipulate Zippers, fresh id - creation is done by threading an IdGen parameter through all of the - (functions which call) functions where new tiles can be created. This - generally follows the state monad pattern. When a fresh Id is required, - the current value of the IdGen is used, and the IdGen is incremented - and must then be returned to the caller. - - The threading of IdGen through essentially all syntax modification - functions presents a significant complication for the action code, - and may eventually be replaced it with a mutable ref. - - WHERE DOES IDGEN LIVE? - - The initial IdGen passed to zipper functions is generally packaged - along with a zipper through the Zipper.state type. Although in - principle the initial IdGen could be set by traversing the zipper - and finding the largest Id, to avoid this traversal we track the - IdGen along with the zipper state. Each editor mode is responsible - for this tracking. Ultimately, each zipper action which can result in - new Ids being created must be sandwiched by calls to - Editors.get_editor_and_id and Editors.put_editor_and_id, to ensure that - IdGen state is tracked between actions and properly serialized to - local storage. - - HOW DO I GENERATE FRESH IDS FOR MY USE CASE? - - Currently there is no easy way to generate fresh IDs in places one - might concievably want them after Term creation, for example in the - elaborator or evaluator. Doing so is a significant change with - indirect implications for architrcture and performance; ask Andrew - about your use case before attempting this. For some uses, a dummy id - may be sufficient; this should be documented and use Id.invalid or - another similar label rather than magic literals. If you do need to - generated genuinely fresh IDs, then you'll need (A) a strategy - to route an IdGen to/from your use site to the aformentioned - Editors functions, and a traversal/mutation strategy within your - context of use. - - IDS IN DYNAMICS: - - Currently, DHExps (as produced by the elaborator and produced/consumed - by the evaluator) do not in general persist ids; the exceptions are - things like holes and tests which have additional metadata which is - accumulated duting evaluation. There are many use cases for tracking - ids more generally during evaluation, but doing so in a principled - way is a large-scale change with architectural implications. - - */ - [@deriving (show({with_path: false}), sexp, yojson)] let sexp_of_t: Uuidm.t => Sexplib.Sexp.t = t => Sexplib.Sexp.Atom(Uuidm.to_string(t)); From bae6457068e48b957a89a1c710531aaf4e9a850e Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 10:24:24 -0400 Subject: [PATCH 100/229] Revert DHDoc_Exp.re --- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index ead18ee4ff..2dc53757b5 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -179,7 +179,7 @@ let rec mk = | BoolLit(b) => DHDoc_common.mk_BoolLit(b) | IntLit(n) => DHDoc_common.mk_IntLit(n) | FloatLit(f) => DHDoc_common.mk_FloatLit(f) - | StringLit(s) => DHDoc_common.mk_StringLit("\"" ++ s ++ "\"") + | StringLit(s) => DHDoc_common.mk_StringLit(s) | TestLit(_) => Doc.text(ExpandingKeyword.to_string(Test)) | Sequence(d1, d2) => let (doc1, doc2) = (go'(d1), go'(d2)); From 19589e175b2e26cc35f919eebeda8fa77f49f37a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 29 Sep 2023 11:46:51 -0400 Subject: [PATCH 101/229] Add constraint_ to Info.pat --- src/haz3lcore/dynamics/Constraint.re | 2 +- src/haz3lcore/statics/Info.re | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 21cb280ad3..c7d325b844 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -1,6 +1,6 @@ open Sexplib.Std; -[@deriving sexp] +[@deriving (show({with_path: false}), sexp, yojson)] type t = | Truth | Falsity diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 57d9f71b4e..9c2015a65d 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -201,6 +201,7 @@ type pat = { cls: Term.Cls.t, status: status_pat, ty: Typ.t, + constraint_: Constraint.t, }; [@deriving (show({with_path: false}), sexp, yojson)] @@ -461,7 +462,17 @@ let derived_pat = (~upat: UPat.t, ~ctx, ~mode, ~ancestors, ~self): pat => { let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - {cls, self, mode, ty, status, ctx, ancestors, term: upat}; + { + cls, + self, + mode, + ty, + status, + ctx, + ancestors, + term: upat, + constraint_: Falsity, + }; }; /* Add derivable attributes for types */ From 6f89c095067d765be23644d4ceb83686593615cc Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sun, 1 Oct 2023 15:01:50 -0400 Subject: [PATCH 102/229] Added ruls_to_info to statics.re --- src/haz3lcore/statics/Statics.re | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 70b92567ce..1d1631d7f4 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -283,7 +283,26 @@ and uexp_to_info_map = es, p_ctxs, ); - // let rec ruls_to_info_map = (xi_pre: Constraint.t, m) => (xi_pre, m); + + let type_of_exp = (rule: UExp.t): Typ.t => { + let (inf, _) = + uexp_to_info_map( + ~ctx=Builtins.ctx_init, + ~ancestors=[], + rule, + Id.Map.empty, + ); + inf.ty; + }; + + let rec ruls_to_info_map = (rules: list(UExp.t)): list(Typ.t) => { + List.fold_left( + (acc, rule) => {List.append(acc, [type_of_exp(rule)])}, + [], + rules, + ); + }; + let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); From 21d28f7398c6dca6d373ef3520b4018618945a2d Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 3 Oct 2023 15:28:55 -0400 Subject: [PATCH 103/229] Exhaust case matching over using _ in Term --- src/haz3lcore/statics/Term.re | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 1294eb55c7..6de5620eda 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -215,8 +215,13 @@ module UTyp = { {name, id: UTPat.rep_id(utpat), kind: Abstract}, ); Rec(name, to_typ(ctx, tbody)); - | Forall(_, tbody) => Forall("?", to_typ(ctx, tbody)) - | Rec(_, tbody) => Rec("?", to_typ(ctx, tbody)) + | Forall({term: Invalid(_), _}, tbody) + | Forall({term: EmptyHole, _}, tbody) + | Forall({term: MultiHole(_), _}, tbody) => + Forall("?", to_typ(ctx, tbody)) + | Rec({term: Invalid(_), _}, tbody) + | Rec({term: EmptyHole, _}, tbody) + | Rec({term: MultiHole(_), _}, tbody) => Rec("?", to_typ(ctx, tbody)) /* The below cases should occur only inside sums */ | Constructor(_) | Ap(_) => Unknown(Internal) From 7ab89b13a391ed68d9033269ba5800ef9697da3e Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 3 Oct 2023 15:30:29 -0400 Subject: [PATCH 104/229] Remove unused code. --- src/haz3lcore/statics/TypBase.re | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 2d158051dc..0a3c7ace31 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -652,33 +652,4 @@ and Kind: { type t = | Singleton(Typ.t) | Abstract; - /* Is not needed as not using debrujin indices */ - /* - let rec incr = (ty: t, i: int): t => { - switch (ty) { - | Var({item: Some(j), name}) => Var({item: Some(i + j), name}) - | Var(_) => ty - | List(ty) => List(incr(ty, i)) - | Arrow(ty1, ty2) => Arrow(incr(ty1, i), incr(ty2, i)) - | Sum(map) => - Sum( - VarMap.map( - ((_, ty)) => - switch (ty) { - | Some(ty) => Some(incr(ty, i)) - | None => None - }, - map, - ), - ) - | Prod(tys) => Prod(List.map(ty => incr(ty, i), tys)) - | Rec({item, name}) => Rec({item: incr(item, i), name}) - | Forall({item, name}) => Forall({item: incr(item, i), name}) - | Int => Int - | Float => Float - | Bool => Bool - | String => String - | Unknown(_) => ty - }; - */ }; From ed3759ffff9c2daf9caf00172688ddf2768e5fbe Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 8 Oct 2023 01:08:24 -0400 Subject: [PATCH 105/229] Added Constraint.Bool/NotBool --- src/haz3lcore/dynamics/Constraint.re | 10 +++++++ src/haz3lcore/dynamics/Incon.re | 42 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index c7d325b844..24b5b40180 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -9,6 +9,8 @@ type t = | NotInt(int) | Float(float) | NotFloat(float) + | Bool(bool) + | NotBool(bool) | String(string) | NotString(string) | And(t, t) @@ -26,6 +28,8 @@ let rec constrains = (c: t, ty: Typ.t): bool => | (Int(_) | NotInt(_), _) => false | (Float(_) | NotFloat(_), Float) => true | (Float(_) | NotFloat(_), _) => false + | (Bool(_) | NotBool(_), Bool) => true + | (Bool(_) | NotBool(_), _) => false | (String(_) | NotString(_), String) => true | (String(_) | NotString(_), _) => false | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) @@ -56,6 +60,8 @@ let rec dual = (c: t): t => | NotInt(n) => Int(n) | Float(n) => NotFloat(n) | NotFloat(n) => Float(n) + | Bool(n) => NotBool(n) + | NotBool(n) => Bool(n) | String(n) => NotString(n) | NotString(n) => String(n) | And(c1, c2) => Or(dual(c1), dual(c2)) @@ -79,6 +85,8 @@ let rec truify = (c: t): t => | NotInt(_) | Float(_) | NotFloat(_) + | Bool(_) + | NotBool(_) | String(_) | NotString(_) => c | And(c1, c2) => And(truify(c1), truify(c2)) @@ -98,6 +106,8 @@ let rec falsify = (c: t): t => | NotInt(_) | Float(_) | NotFloat(_) + | Bool(_) + | NotBool(_) | String(_) | NotString(_) => c | And(c1, c2) => And(falsify(c1), falsify(c2)) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 5d41604928..d52fa6662b 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -56,6 +56,34 @@ let is_inconsistent_float = (xis: list(Constraint.t)): bool => { }; }; +let is_inconsistent_bool = (xis: list(Constraint.t)): bool => { + let (bool_set, not_bool_list) = + List.fold_left( + ((bool_set, not_bool_list), xi: Constraint.t) => + switch (xi) { + | Bool(b) => (BoolSet.add(b, bool_set), not_bool_list) + | NotBool(b) => (bool_set, [b, ...not_bool_list]) + | _ => failwith("input can only be Bool | NotBool") + }, + (BoolSet.empty, []), + xis, + ); + if (BoolSet.cardinal(bool_set) > 1) { + true; + } else { + List.fold_left( + (incon, b) => + if (incon) { + incon; + } else { + BoolSet.mem(b, bool_set); + }, + false, + not_bool_list, + ); + }; +}; + let is_inconsistent_string = (xis: list(Constraint.t)): bool => { let (string_set, not_string_list) = List.fold_left( @@ -170,6 +198,20 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => | (fs, []) => is_inconsistent_float(fs) | (fs, other) => is_inconsistent(~may, other @ fs) } + | Bool(_) + | NotBool(_) => + switch ( + List.partition( + fun + | Constraint.Bool(_) + | NotBool(_) => true + | _ => false, + xis, + ) + ) { + | (fs, []) => is_inconsistent_bool(fs) + | (fs, other) => is_inconsistent(~may, other @ fs) + } | String(_) | NotString(_) => switch ( From 45c9e474f10f011cb9814a2bde37557eeff4b1ce Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 8 Oct 2023 03:51:52 -0400 Subject: [PATCH 106/229] Add fixed_constraint_pat --- src/haz3lcore/statics/Info.re | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 9c2015a65d..242e0b059a 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -442,6 +442,14 @@ let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => | NotInHole(ok) => fixed_typ_ok(ok) }; +let fixed_constraint_pat = + (ctx, mode: Mode.t, self: Self.pat, constraint_: Constraint.t) + : Constraint.t => + switch (status_pat(ctx, mode, self)) { + | InHole(_) => Constraint.Hole + | NotInHole(_) => constraint_ + }; + let fixed_typ_exp = (ctx, mode: Mode.t, self: Self.exp): Typ.t => switch (status_exp(ctx, mode, self)) { | InHole(_) => Unknown(Internal) @@ -458,21 +466,13 @@ let derived_exp = }; /* Add derivable attributes for pattern terms */ -let derived_pat = (~upat: UPat.t, ~ctx, ~mode, ~ancestors, ~self): pat => { +let derived_pat = + (~upat: UPat.t, ~ctx, ~mode, ~ancestors, ~self, ~constraint_): pat => { let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - { - cls, - self, - mode, - ty, - status, - ctx, - ancestors, - term: upat, - constraint_: Falsity, - }; + let constraint_ = fixed_constraint_pat(ctx, mode, self, constraint_); + {cls, self, mode, ty, status, ctx, ancestors, term: upat, constraint_}; }; /* Add derivable attributes for types */ From 0f631197ac9283321937184f03ad1206d3eb1575 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 8 Oct 2023 04:12:13 -0400 Subject: [PATCH 107/229] Implemented constraint emission for simple cases --- src/haz3lcore/statics/Statics.re | 41 +++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 1d1631d7f4..ccefc4eb6d 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -370,12 +370,19 @@ and upat_to_info_map = m: Map.t, ) : (Info.pat, Map.t) => { - let add = (~self, ~ctx, m) => { + let add = (~self, ~ctx, ~constraint_, m) => { let info = - Info.derived_pat(~upat, ~ctx, ~mode, ~ancestors, ~self=Common(self)); + Info.derived_pat( + ~upat, + ~ctx, + ~mode, + ~ancestors, + ~self=Common(self), + ~constraint_, + ); (info, add_info(ids, InfoPat(info), m)); }; - let atomic = self => add(~self, ~ctx, m); + let atomic = (self, constraint_) => add(~self, ~ctx, ~constraint_, m); let ancestors = [UPat.rep_id(upat)] @ ancestors; let go = upat_to_info_map(~is_synswitch, ~ancestors); let unknown = Typ.Unknown(is_synswitch ? SynSwitch : Internal); @@ -386,17 +393,18 @@ and upat_to_info_map = |> (((info, m)) => (info.ctx, tys @ [info.ty], m)), (ctx, [], m), ); + let hole = self => atomic(self, Constraint.Hole); switch (term) { | MultiHole(tms) => let (_, m) = multi(~ctx, ~ancestors, m, tms); - add(~self=IsMulti, ~ctx, m); - | Invalid(token) => atomic(BadToken(token)) - | EmptyHole => atomic(Just(unknown)) - | Int(_) => atomic(Just(Int)) - | Float(_) => atomic(Just(Float)) + add(~self=IsMulti, ~ctx, ~constraint_=Constraint.Hole, m); + | Invalid(token) => hole(BadToken(token)) + | EmptyHole => hole(Just(unknown)) + | Int(int) => atomic(Just(Int), Constraint.Int(int)) + | Float(float) => atomic(Just(Float), Constraint.Float(float)) | Triv => atomic(Just(Prod([]))) - | Bool(_) => atomic(Just(Bool)) - | String(_) => atomic(Just(String)) + | Bool(bool) => atomic(Just(Bool), Constraint.Bool(bool)) + | String(string) => atomic(Just(String), Constraint.String(string)) | ListLit(ps) => let ids = List.map(UPat.rep_id, ps); let modes = Mode.of_list_lit(ctx, List.length(ps), mode); @@ -407,7 +415,7 @@ and upat_to_info_map = let (tl, m) = go(~ctx=hd.ctx, ~mode=Mode.of_cons_tl(ctx, mode, hd.ty), tl, m); add(~self=Just(List(hd.ty)), ~ctx=tl.ctx, m); - | Wild => atomic(Just(unknown)) + | Wild => atomic(Just(unknown), Constraint.Truth) | Var(name) => /* NOTE: The self type assigned to pattern variables (Unknown) may be SynSwitch, but SynSwitch is never added to the context; @@ -415,14 +423,19 @@ and upat_to_info_map = let ctx_typ = Info.fixed_typ_pat(ctx, mode, Common(Just(Unknown(Internal)))); let entry = Ctx.VarEntry({name, id: UPat.rep_id(upat), typ: ctx_typ}); - add(~self=Just(unknown), ~ctx=Ctx.extend(ctx, entry), m); + add( + ~self=Just(unknown), + ~ctx=Ctx.extend(ctx, entry), + ~constraint_=Constraint.Truth, + m, + ); | Tuple(ps) => let modes = Mode.of_prod(ctx, mode, List.length(ps)); let (ctx, tys, m) = ctx_fold(ctx, m, ps, modes); add(~self=Just(Prod(tys)), ~ctx, m); | Parens(p) => let (p, m) = go(~ctx, ~mode, p, m); - add(~self=Just(p.ty), ~ctx=p.ctx, m); + add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr)) | Ap(fn, arg) => let fn_mode = Mode.of_ap(ctx, mode, UPat.ctr_name(fn)); @@ -433,7 +446,7 @@ and upat_to_info_map = | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); - add(~self=Just(ann.ty), ~ctx=p.ctx, m); + add(~self=Just(ann.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); }; } and utyp_to_info_map = From d73d4ac084acb7452635962332a3252b0cd04190 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Mon, 9 Oct 2023 09:39:47 -0400 Subject: [PATCH 108/229] Wrote pattern to constraint for unit, tuple and list. --- src/haz3lcore/statics/Statics.re | 57 ++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ccefc4eb6d..5ac79c1c2c 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -388,10 +388,17 @@ and upat_to_info_map = let unknown = Typ.Unknown(is_synswitch ? SynSwitch : Internal); let ctx_fold = (ctx: Ctx.t, m) => List.fold_left2( - ((ctx, tys, m), e, mode) => + ((ctx, tys, cons, m), e, mode) => go(~ctx, ~mode, e, m) - |> (((info, m)) => (info.ctx, tys @ [info.ty], m)), - (ctx, [], m), + |> ( + ((info, m)) => ( + info.ctx, + tys @ [info.ty], + cons @ [info.constraint_], + m, + ) + ), + (ctx, [], [], m), ); let hole = self => atomic(self, Constraint.Hole); switch (term) { @@ -402,19 +409,36 @@ and upat_to_info_map = | EmptyHole => hole(Just(unknown)) | Int(int) => atomic(Just(Int), Constraint.Int(int)) | Float(float) => atomic(Just(Float), Constraint.Float(float)) - | Triv => atomic(Just(Prod([]))) + | Triv => atomic(Just(Prod([])), Constraint.Truth) | Bool(bool) => atomic(Just(Bool), Constraint.Bool(bool)) | String(string) => atomic(Just(String), Constraint.String(string)) | ListLit(ps) => let ids = List.map(UPat.rep_id, ps); let modes = Mode.of_list_lit(ctx, List.length(ps), mode); - let (ctx, tys, m) = ctx_fold(ctx, m, ps, modes); - add(~self=Self.listlit(~empty=unknown, ctx, tys, ids), ~ctx, m); + let (ctx, tys, cons, m) = ctx_fold(ctx, m, ps, modes); + let rec cons_fold_list = cs => + switch (cs) { + | [] => Constraint.InjL(Constraint.Truth) // Left = nil, Right = cons + | [hd, ...tl] => + Constraint.InjR(Constraint.Pair(hd, cons_fold_list(tl))) + }; + add( + ~self=Self.listlit(~empty=unknown, ctx, tys, ids), + ~ctx, + ~constraint_=cons_fold_list(cons), + m, + ); | Cons(hd, tl) => let (hd, m) = go(~ctx, ~mode=Mode.of_cons_hd(ctx, mode), hd, m); let (tl, m) = go(~ctx=hd.ctx, ~mode=Mode.of_cons_tl(ctx, mode, hd.ty), tl, m); - add(~self=Just(List(hd.ty)), ~ctx=tl.ctx, m); + add( + ~self=Just(List(hd.ty)), + ~ctx=tl.ctx, + ~constraint_= + Constraint.InjR(Constraint.Pair(hd.constraint_, tl.constraint_)), + m, + ); | Wild => atomic(Just(unknown), Constraint.Truth) | Var(name) => /* NOTE: The self type assigned to pattern variables (Unknown) @@ -431,18 +455,29 @@ and upat_to_info_map = ); | Tuple(ps) => let modes = Mode.of_prod(ctx, mode, List.length(ps)); - let (ctx, tys, m) = ctx_fold(ctx, m, ps, modes); - add(~self=Just(Prod(tys)), ~ctx, m); + let (ctx, tys, cons, m) = ctx_fold(ctx, m, ps, modes); + let rec cons_fold_tuple = cs => + switch (cs) { + | [] => Constraint.Truth + | [elt] => elt + | [hd, ...tl] => Constraint.Pair(hd, cons_fold_tuple(tl)) + }; + add( + ~self=Just(Prod(tys)), + ~ctx, + ~constraint_=cons_fold_tuple(cons), + m, + ); | Parens(p) => let (p, m) = go(~ctx, ~mode, p, m); add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); - | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr)) + | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr), Constraint.Falsity) // TODO | Ap(fn, arg) => let fn_mode = Mode.of_ap(ctx, mode, UPat.ctr_name(fn)); let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); let (ty_in, ty_out) = Typ.matched_arrow(ctx, fn.ty); let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); - add(~self=Just(ty_out), ~ctx=arg.ctx, m); + add(~self=Just(ty_out), ~ctx=arg.ctx, ~constraint_=arg.constraint_, m); | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); From 46b6d864c61b9d3258858eb50330a024e142a589 Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 14 Oct 2023 16:56:03 -0400 Subject: [PATCH 109/229] Generating Self.exp from constraints --- src/haz3lcore/statics/Statics.re | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 5ac79c1c2c..542cf136e4 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -302,8 +302,28 @@ and uexp_to_info_map = rules, ); }; - - let e_tys = List.map(Info.exp_ty, es); + let (pats, exps) = List.split(rules); + let final_constraint = + List.map( + (pat: UPat.t): Constraint.t => { + let (patInfo, _) = + upat_to_info_map( + ~is_synswitch=true, + ~ctx, + ~ancestors, + ~mode, + pat, + m, + ); + patInfo.constraint_; + }, + pats, + ); + let exhaustive = Incon.is_exhaustive(final_constraint); + let generatedSelf= switch(exhaustive){ + |true =>Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); + |false =>InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); + }; let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); add'( From 932eff310a67101c116038f990df8fa4655b9bfb Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 14 Oct 2023 17:26:00 -0400 Subject: [PATCH 110/229] Folded result of is_exhaustive to generate Self.exp --- src/haz3lcore/statics/Statics.re | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 542cf136e4..ae8be2617c 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -303,7 +303,7 @@ and uexp_to_info_map = ); }; let (pats, exps) = List.split(rules); - let final_constraint = + let get_constraints = List.map( (pat: UPat.t): Constraint.t => { let (patInfo, _) = @@ -319,8 +319,12 @@ and uexp_to_info_map = }, pats, ); - let exhaustive = Incon.is_exhaustive(final_constraint); - let generatedSelf= switch(exhaustive){ + let final_constraint = List.fold_left( + (acc,c) => {Incon.is_exhaustive(c) && acc}, + true, + get_constraints, + ); + let generatedSelf= switch(final_constraint){ |true =>Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); |false =>InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); }; From 4149adcdfa0a0738b006dd9e5d26389e20c658ef Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 14 Oct 2023 17:46:39 -0400 Subject: [PATCH 111/229] Indicated that InexhaustiveMatch is from Self.re --- src/haz3lcore/statics/Statics.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ae8be2617c..4ac3bcda39 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -325,8 +325,8 @@ and uexp_to_info_map = get_constraints, ); let generatedSelf= switch(final_constraint){ - |true =>Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); - |false =>InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); + |true =>Self.Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); + |false =>Self.InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); }; let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); From 188d22225a2007b22beb2388feaaf11dc939fc6a Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 14 Oct 2023 18:00:03 -0400 Subject: [PATCH 112/229] Error fixes --- src/haz3lcore/statics/Statics.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 4ac3bcda39..1918892641 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -324,9 +324,9 @@ and uexp_to_info_map = true, get_constraints, ); - let generatedSelf= switch(final_constraint){ + let generatedSelf: Self.exp= switch(final_constraint){ |true =>Self.Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); - |false =>Self.InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); + |false =>InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); }; let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); From fc6f0ce5d2c18d1e82c29696bc2f9ef18f03ccb9 Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 14 Oct 2023 18:08:10 -0400 Subject: [PATCH 113/229] used Info.exp_ty over ruls_to_info_map --- src/haz3lcore/statics/Statics.re | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 1918892641..784e542e23 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -324,10 +324,12 @@ and uexp_to_info_map = true, get_constraints, ); + let e_tys = List.map(Info.exp_ty, es); let generatedSelf: Self.exp= switch(final_constraint){ - |true =>Self.Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids)); - |false =>InexhaustiveMatch(Common(Self.match(ctx, ruls_to_info_map(exps), branch_ids))); + |true =>Self.Common(Self.match(ctx, e_tys, branch_ids)); + |false =>InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))); }; + let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); add'( From 38d1232f11188463cc5ca02e5503186bc185f8ef Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sun, 15 Oct 2023 21:42:48 -0400 Subject: [PATCH 114/229] Combined constraints with or_constraints() --- src/haz3lcore/statics/Statics.re | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 784e542e23..80d0685295 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -295,15 +295,17 @@ and uexp_to_info_map = inf.ty; }; - let rec ruls_to_info_map = (rules: list(UExp.t)): list(Typ.t) => { + //ruls_to_info_map was implemented but not sure where to use yet + [@warning "-26"] + let ruls_to_info_map = (rules: list(UExp.t)): list(Typ.t) => { List.fold_left( (acc, rule) => {List.append(acc, [type_of_exp(rule)])}, [], rules, ); }; - let (pats, exps) = List.split(rules); - let get_constraints = + let (pats, _) = List.split(rules); + let get_constraints = List.map( (pat: UPat.t): Constraint.t => { let (patInfo, _) = @@ -319,17 +321,16 @@ and uexp_to_info_map = }, pats, ); - let final_constraint = List.fold_left( - (acc,c) => {Incon.is_exhaustive(c) && acc}, - true, - get_constraints, - ); + let final_constraint = Constraint.or_constraints(get_constraints); let e_tys = List.map(Info.exp_ty, es); - let generatedSelf: Self.exp= switch(final_constraint){ - |true =>Self.Common(Self.match(ctx, e_tys, branch_ids)); - |false =>InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))); - }; - + + //generate_self is generating a Self.exp that is yet to be utilized + [@warning "-26"] + let generate_self: Self.exp = + Incon.is_exhaustive(final_constraint) + ? Self.Common(Self.match(ctx, e_tys, branch_ids)) + : InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))); + let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); add'( From 6ff3c31e4fc93ea422a69c831ce707fa6e1b6681 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 19 Oct 2023 23:55:43 -0400 Subject: [PATCH 115/229] Extended ConstructorEntry, Part I --- src/haz3lcore/statics/Statics.re | 7 ++++++- src/haz3lcore/statics/TypBase.re | 8 ++++---- src/haz3lweb/view/CtxInspector.re | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 80d0685295..1e0392c80c 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -504,7 +504,12 @@ and upat_to_info_map = let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); let (ty_in, ty_out) = Typ.matched_arrow(ctx, fn.ty); let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); - add(~self=Just(ty_out), ~ctx=arg.ctx, ~constraint_=arg.constraint_, m); + add( + ~self=Just(ty_out), + ~ctx=arg.ctx, + ~constraint_=Constraint.Falsity, + m, + ); // TODO | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 3f614145ab..4babadf994 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -443,7 +443,7 @@ and Ctx: { [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - | ConstructorEntry(var_entry) + | ConstructorEntry(var_entry, Constraint.t => Constraint.t) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -482,7 +482,7 @@ and Ctx: { [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - | ConstructorEntry(var_entry) + | ConstructorEntry(var_entry, Constraint.t => Constraint.t) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -517,7 +517,7 @@ and Ctx: { let get_id: entry => Id.t = fun | VarEntry({id, _}) - | ConstructorEntry({id, _}) + | ConstructorEntry({id, _}, _) | TVarEntry({id, _}) => id; let lookup_var = (ctx: t, name: string): option(var_entry) => @@ -591,7 +591,7 @@ and Ctx: { ((ctx, term_set, typ_set), entry) => { switch (entry) { | VarEntry({name, _}) - | ConstructorEntry({name, _}) => + | ConstructorEntry({name, _}, _) => VarSet.mem(name, term_set) ? (ctx, term_set, typ_set) : ([entry, ...ctx], VarSet.add(name, term_set), typ_set) diff --git a/src/haz3lweb/view/CtxInspector.re b/src/haz3lweb/view/CtxInspector.re index a148f149cc..dbfe664b38 100644 --- a/src/haz3lweb/view/CtxInspector.re +++ b/src/haz3lweb/view/CtxInspector.re @@ -16,7 +16,7 @@ let context_entry_view = (~inject, entry: Haz3lcore.Ctx.entry): Node.t => { ); switch (entry) { | VarEntry({name, typ, _}) - | ConstructorEntry({name, typ, _}) => + | ConstructorEntry({name, typ, _}, _) => div_c( "context-entry", [ From d719567d5cc36038da5ece27a969d37f89af31ab Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 00:45:37 -0400 Subject: [PATCH 116/229] Extended ConstructorEntry, Part II --- src/haz3lcore/statics/TypBase.re | 51 ++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 4babadf994..bbffd4d7d1 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -531,7 +531,7 @@ and Ctx: { let lookup_ctr = (ctx: t, name: string): option(var_entry) => List.find_map( fun - | ConstructorEntry(t) when t.name == name => Some(t) + | ConstructorEntry(t, _) when t.name == name => Some(t) | _ => None, ctx, ); @@ -542,21 +542,40 @@ and Ctx: { | None => false }; - let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => - List.map( - ((ctr, typ)) => - ConstructorEntry({ - name: ctr, - id, - typ: - switch (typ) { - | None => Var(name) - | Some(typ) => Arrow(typ, Var(name)) - }, - }), - ctrs, - ) - @ ctx; + let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => { + let (ctx, _, _) = + List.fold_left( + ((ctx, nth, wrap), (ctr, typ)) => { + // List.length(ctrs) == 0: EmptyHole + // List.length(ctrs) == 1: Type variable not found + assert(List.length(ctrs) > 1); + + // List.length(ctrs) == 2: + // nth == 0: xi => InjL(xi) + // nth == 1: xi => InjR(InjL(xi)) + // nth == 2: xi => InjR(InjR(xi)) + let constraint_ctor = xi => + wrap(nth == List.length(ctrs) - 1 ? Constraint.InjL(xi) : xi); + let entry = + ConstructorEntry( + { + name: ctr, + id, + typ: + switch (typ) { + | None => Var(name) + | Some(typ) => Arrow(typ, Var(name)) + }, + }, + constraint_ctor, + ); + ([entry, ...ctx], nth + 1, xi => wrap(Constraint.InjR(xi))); + }, + (ctx, 0, Fun.id), + ctrs, + ); + ctx; + }; let subtract_prefix = (ctx: t, prefix_ctx: t): option(t) => { // NOTE: does not check that the prefix is an actual prefix From f132e82b9e9baf9515974c8f03be64246cfaa76f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 01:24:00 -0400 Subject: [PATCH 117/229] Extended ConstructorEntry, Part III --- src/haz3lcore/statics/TypBase.re | 57 ++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index bbffd4d7d1..5192c96314 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -443,7 +443,8 @@ and Ctx: { [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - | ConstructorEntry(var_entry, Constraint.t => Constraint.t) + // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ + | ConstructorEntry(var_entry, int) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -482,7 +483,8 @@ and Ctx: { [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - | ConstructorEntry(var_entry, Constraint.t => Constraint.t) + // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ + | ConstructorEntry(var_entry, int) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -543,19 +545,40 @@ and Ctx: { }; let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => { - let (ctx, _, _) = + // let (ctx, _, _) = + // List.fold_left( + // ((ctx, nth, wrap), (ctr, typ)) => { + // // List.length(ctrs) == 0: EmptyHole + // // List.length(ctrs) == 1: Type variable not found + // assert(List.length(ctrs) > 1); + + // // List.length(ctrs) == 2: + // // nth == 0: xi => InjL(xi) + // // nth == 1: xi => InjR(InjL(xi)) + // // nth == 2: xi => InjR(InjR(xi)) + // let constraint_ctor = xi => + // wrap(nth == List.length(ctrs) - 1 ? Constraint.InjL(xi) : xi); + // let entry = + // ConstructorEntry( + // { + // name: ctr, + // id, + // typ: + // switch (typ) { + // | None => Var(name) + // | Some(typ) => Arrow(typ, Var(name)) + // }, + // }, + // constraint_ctor, + // ); + // ([entry, ...ctx], nth + 1, xi => wrap(Constraint.InjR(xi))); + // }, + // (ctx, 0, Fun.id), + // ctrs, + // ); + let (ctx, _) = List.fold_left( - ((ctx, nth, wrap), (ctr, typ)) => { - // List.length(ctrs) == 0: EmptyHole - // List.length(ctrs) == 1: Type variable not found - assert(List.length(ctrs) > 1); - - // List.length(ctrs) == 2: - // nth == 0: xi => InjL(xi) - // nth == 1: xi => InjR(InjL(xi)) - // nth == 2: xi => InjR(InjR(xi)) - let constraint_ctor = xi => - wrap(nth == List.length(ctrs) - 1 ? Constraint.InjL(xi) : xi); + ((ctx, nth), (ctr, typ)) => { let entry = ConstructorEntry( { @@ -567,11 +590,11 @@ and Ctx: { | Some(typ) => Arrow(typ, Var(name)) }, }, - constraint_ctor, + nth, ); - ([entry, ...ctx], nth + 1, xi => wrap(Constraint.InjR(xi))); + ([entry, ...ctx], nth + 1); }, - (ctx, 0, Fun.id), + (ctx, 0), ctrs, ); ctx; From 1e543d546df00a452f78d92f906a48a948cdee63 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 03:06:52 -0400 Subject: [PATCH 118/229] Fixed the Pair bug in Constraint.constrains --- src/haz3lcore/dynamics/Constraint.re | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 24b5b40180..6d869336f4 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -18,6 +18,7 @@ type t = | InjL(t) | InjR(t) | Pair(t, t); +// | Tuple(list(t)); let rec constrains = (c: t, ty: Typ.t): bool => switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { @@ -48,7 +49,12 @@ let rec constrains = (c: t, ty: Typ.t): bool => | map' => constrains(c2, Sum(map')) } | (InjR(_), _) => false - | (Pair(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) + | (Pair(c1, c2), Prod([ty_hd, ...ty_tl])) => + constrains(c1, ty_hd) && constrains(c2, Prod(ty_tl)) + | (Pair(_), _) => false + // | (Tuple(cs), Prod(tys)) when List.length(cs) == List.length(tys) => + // List.for_all2(constrains, cs, tys) + // | (Tuple(_), _) => false }; let rec dual = (c: t): t => @@ -60,8 +66,8 @@ let rec dual = (c: t): t => | NotInt(n) => Int(n) | Float(n) => NotFloat(n) | NotFloat(n) => Float(n) - | Bool(n) => NotBool(n) - | NotBool(n) => Bool(n) + | Bool(b) => NotBool(b) + | NotBool(b) => Bool(b) | String(n) => NotString(n) | NotString(n) => String(n) | And(c1, c2) => Or(dual(c1), dual(c2)) @@ -73,6 +79,7 @@ let rec dual = (c: t): t => Pair(c1, dual(c2)), Or(Pair(dual(c1), c2), Pair(dual(c1), dual(c2))), ) + // | Tuple(cs) => // TODO }; /** substitute Truth for Hole */ From cb1963da11ec935541431cc74b6c3220cb08eaf4 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 03:07:07 -0400 Subject: [PATCH 119/229] Added Constraint.of_nth_variant --- src/haz3lcore/dynamics/Constraint.re | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 6d869336f4..5fb678367d 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -145,3 +145,13 @@ let rec or_constraints = (lst: list(t)): t => | [xi] => xi | [xi, ...xis] => Or(xi, or_constraints(xis)) }; + +// Temporary name +let rec of_nth_variant = (num_variants, nth): (t => t) => + if (num_variants == 1) { + Fun.id; + } else if (nth == 0) { + xi => InjL(xi); + } else { + xi => InjR(xi |> of_nth_variant(num_variants - 1, nth - 1)); + }; From ffd083977c420c9e6310d07767e349b694e554b5 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 03:15:23 -0400 Subject: [PATCH 120/229] Extended ConstructorEntry, Part IV --- src/haz3lcore/statics/TypBase.re | 50 ++++++++++++++++++++----------- src/haz3lweb/view/CtxInspector.re | 2 +- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 5192c96314..323a49c031 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -440,11 +440,19 @@ and Ctx: { kind: Kind.t, }; + [@deriving (show({with_path: false}), sexp, yojson)] + type constructor_entry = { + name: Var.t, + id: Id.t, + typ: Typ.t, + nth: int // temporary name + }; + [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ - | ConstructorEntry(var_entry, int) + | ConstructorEntry(constructor_entry) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -458,7 +466,7 @@ and Ctx: { let lookup_alias: (t, TypVar.t) => option(Typ.t); let get_id: entry => Id.t; let lookup_var: (t, string) => option(var_entry); - let lookup_ctr: (t, string) => option(var_entry); + let lookup_ctr: (t, string) => option(constructor_entry); let is_alias: (t, TypVar.t) => bool; let add_ctrs: (t, TypVar.t, Id.t, Typ.sum_map) => t; let subtract_prefix: (t, t) => option(t); @@ -480,11 +488,19 @@ and Ctx: { kind: Kind.t, }; + [@deriving (show({with_path: false}), sexp, yojson)] + type constructor_entry = { + name: Var.t, + id: Id.t, + typ: Typ.t, + nth: int // temporary name + }; + [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ - | ConstructorEntry(var_entry, int) + | ConstructorEntry(constructor_entry) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -519,7 +535,7 @@ and Ctx: { let get_id: entry => Id.t = fun | VarEntry({id, _}) - | ConstructorEntry({id, _}, _) + | ConstructorEntry({id, _}) | TVarEntry({id, _}) => id; let lookup_var = (ctx: t, name: string): option(var_entry) => @@ -530,10 +546,10 @@ and Ctx: { ctx, ); - let lookup_ctr = (ctx: t, name: string): option(var_entry) => + let lookup_ctr = (ctx: t, name: string): option(constructor_entry) => List.find_map( fun - | ConstructorEntry(t, _) when t.name == name => Some(t) + | ConstructorEntry(t) when t.name == name => Some(t) | _ => None, ctx, ); @@ -580,18 +596,16 @@ and Ctx: { List.fold_left( ((ctx, nth), (ctr, typ)) => { let entry = - ConstructorEntry( - { - name: ctr, - id, - typ: - switch (typ) { - | None => Var(name) - | Some(typ) => Arrow(typ, Var(name)) - }, - }, + ConstructorEntry({ + name: ctr, + id, + typ: + switch (typ) { + | None => Var(name) + | Some(typ) => Arrow(typ, Var(name)) + }, nth, - ); + }); ([entry, ...ctx], nth + 1); }, (ctx, 0), @@ -633,7 +647,7 @@ and Ctx: { ((ctx, term_set, typ_set), entry) => { switch (entry) { | VarEntry({name, _}) - | ConstructorEntry({name, _}, _) => + | ConstructorEntry({name, _}) => VarSet.mem(name, term_set) ? (ctx, term_set, typ_set) : ([entry, ...ctx], VarSet.add(name, term_set), typ_set) diff --git a/src/haz3lweb/view/CtxInspector.re b/src/haz3lweb/view/CtxInspector.re index dbfe664b38..a148f149cc 100644 --- a/src/haz3lweb/view/CtxInspector.re +++ b/src/haz3lweb/view/CtxInspector.re @@ -16,7 +16,7 @@ let context_entry_view = (~inject, entry: Haz3lcore.Ctx.entry): Node.t => { ); switch (entry) { | VarEntry({name, typ, _}) - | ConstructorEntry({name, typ, _}, _) => + | ConstructorEntry({name, typ, _}) => div_c( "context-entry", [ From 5445ddf142cecca8aeb4dd88a048b5bfac6aa9ad Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 04:47:05 -0400 Subject: [PATCH 121/229] Added Constraint.of_ap and Constraint.of_ctr --- src/haz3lcore/dynamics/Constraint.re | 13 +++++++++++++ src/haz3lcore/statics/Statics.re | 3 ++- src/haz3lcore/statics/TypBase.re | 10 ++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 5fb678367d..a8d453233c 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -155,3 +155,16 @@ let rec of_nth_variant = (num_variants, nth): (t => t) => } else { xi => InjR(xi |> of_nth_variant(num_variants - 1, nth - 1)); }; + +let of_ap = (ctx, ctr: option(Constructor.t), arg: t): t => + switch (ctr) { + | Some(name) => + switch (Ctx.lookup_ctr(ctx, name)) { + | None => Hole // TODO: review + | Some({num_variants, nth, _}) => + arg |> of_nth_variant(num_variants, nth) + } + | None => Hole // TODO: review + }; + +let of_ctr = (ctx, name) => of_ap(ctx, Some(name), Truth); diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 1e0392c80c..f9b90450ee 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -500,7 +500,8 @@ and upat_to_info_map = add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr), Constraint.Falsity) // TODO | Ap(fn, arg) => - let fn_mode = Mode.of_ap(ctx, mode, UPat.ctr_name(fn)); + let ctr = UPat.ctr_name(fn); + let fn_mode = Mode.of_ap(ctx, mode, ctr); let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); let (ty_in, ty_out) = Typ.matched_arrow(ctx, fn.ty); let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 323a49c031..e80fa6e972 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -445,7 +445,9 @@ and Ctx: { name: Var.t, id: Id.t, typ: Typ.t, - nth: int // temporary name + /* Temporary variables. Better implementation is a TO-DO. */ + nth: int, + num_variants: int, }; [@deriving (show({with_path: false}), sexp, yojson)] @@ -493,7 +495,9 @@ and Ctx: { name: Var.t, id: Id.t, typ: Typ.t, - nth: int // temporary name + /* Temporary variables. Better implementation is a TO-DO. */ + nth: int, + num_variants: int, }; [@deriving (show({with_path: false}), sexp, yojson)] @@ -592,6 +596,7 @@ and Ctx: { // (ctx, 0, Fun.id), // ctrs, // ); + let num_variants = List.length(ctrs); let (ctx, _) = List.fold_left( ((ctx, nth), (ctr, typ)) => { @@ -605,6 +610,7 @@ and Ctx: { | Some(typ) => Arrow(typ, Var(name)) }, nth, + num_variants, }); ([entry, ...ctx], nth + 1); }, From 1500efe5baff21f0b28d9afb74a6ac96faa2ddff Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 04:53:43 -0400 Subject: [PATCH 122/229] Constraint emission for Constructor and Ap --- src/haz3lcore/dynamics/Constraint.re | 6 +++--- src/haz3lcore/statics/Statics.re | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index a8d453233c..f2ed742299 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -147,13 +147,13 @@ let rec or_constraints = (lst: list(t)): t => }; // Temporary name -let rec of_nth_variant = (num_variants, nth): (t => t) => +let rec ctr_of_nth_variant = (num_variants, nth): (t => t) => if (num_variants == 1) { Fun.id; } else if (nth == 0) { xi => InjL(xi); } else { - xi => InjR(xi |> of_nth_variant(num_variants - 1, nth - 1)); + xi => InjR(xi |> ctr_of_nth_variant(num_variants - 1, nth - 1)); }; let of_ap = (ctx, ctr: option(Constructor.t), arg: t): t => @@ -162,7 +162,7 @@ let of_ap = (ctx, ctr: option(Constructor.t), arg: t): t => switch (Ctx.lookup_ctr(ctx, name)) { | None => Hole // TODO: review | Some({num_variants, nth, _}) => - arg |> of_nth_variant(num_variants, nth) + arg |> ctr_of_nth_variant(num_variants, nth) } | None => Hole // TODO: review }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index f9b90450ee..61f97aa64a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -498,7 +498,8 @@ and upat_to_info_map = | Parens(p) => let (p, m) = go(~ctx, ~mode, p, m); add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); - | Constructor(ctr) => atomic(Self.of_ctr(ctx, ctr), Constraint.Falsity) // TODO + | Constructor(ctr) => + atomic(Self.of_ctr(ctx, ctr), Constraint.of_ctr(ctx, ctr)) | Ap(fn, arg) => let ctr = UPat.ctr_name(fn); let fn_mode = Mode.of_ap(ctx, mode, ctr); @@ -508,9 +509,9 @@ and upat_to_info_map = add( ~self=Just(ty_out), ~ctx=arg.ctx, - ~constraint_=Constraint.Falsity, + ~constraint_=Constraint.of_ap(ctx, ctr, arg.constraint_), m, - ); // TODO + ); | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); From aa7906ec5b87860dce2e1d15984a07d3b187647f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 05:02:38 -0400 Subject: [PATCH 123/229] Match Self generation code simplification --- src/haz3lcore/statics/Statics.re | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 61f97aa64a..27b794a34a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -324,20 +324,15 @@ and uexp_to_info_map = let final_constraint = Constraint.or_constraints(get_constraints); let e_tys = List.map(Info.exp_ty, es); - //generate_self is generating a Self.exp that is yet to be utilized - [@warning "-26"] - let generate_self: Self.exp = + let unwrapped_self: Self.exp = + Common(Self.match(ctx, e_tys, branch_ids)); + let self = Incon.is_exhaustive(final_constraint) - ? Self.Common(Self.match(ctx, e_tys, branch_ids)) - : InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))); + ? unwrapped_self : InexhaustiveMatch(unwrapped_self); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - add'( - ~self=InexhaustiveMatch(Common(Self.match(ctx, e_tys, branch_ids))), - ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), - m, - ); + add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => let m = utpat_to_info_map(~ctx, ~ancestors, typat, m) |> snd; switch (typat.term) { From 7a8389001e9db96b614f17e4b27b9365a79dce23 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 05:05:26 -0400 Subject: [PATCH 124/229] Code simplification part II --- src/haz3lcore/statics/Statics.re | 35 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 27b794a34a..0f7e91c410 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -272,6 +272,22 @@ and uexp_to_info_map = let (scrut, m) = go(~mode=Syn, scrut, m); let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); + let xis = + List.map( + (pat: UPat.t): Constraint.t => { + let (patInfo, _) = + upat_to_info_map( + ~is_synswitch=true, + ~ctx, + ~ancestors, + ~mode, + pat, + m, + ); + patInfo.constraint_; + }, + ps, + ); let (ps, m) = map_m(go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), ps, m); let p_ctxs = List.map(Info.pat_ctx, ps); @@ -304,24 +320,7 @@ and uexp_to_info_map = rules, ); }; - let (pats, _) = List.split(rules); - let get_constraints = - List.map( - (pat: UPat.t): Constraint.t => { - let (patInfo, _) = - upat_to_info_map( - ~is_synswitch=true, - ~ctx, - ~ancestors, - ~mode, - pat, - m, - ); - patInfo.constraint_; - }, - pats, - ); - let final_constraint = Constraint.or_constraints(get_constraints); + let final_constraint = Constraint.or_constraints(xis); let e_tys = List.map(Info.exp_ty, es); let unwrapped_self: Self.exp = From 8ab8464cb7d079bd891c72c4e9cf15115f026aae Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 05:51:52 -0400 Subject: [PATCH 125/229] rules_to_info_map --- src/haz3lcore/statics/Info.re | 1 + src/haz3lcore/statics/Statics.re | 73 ++++++++++---------------------- 2 files changed, 23 insertions(+), 51 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 242e0b059a..a68171bc52 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -257,6 +257,7 @@ let exp_co_ctx: exp => CoCtx.t = ({co_ctx, _}) => co_ctx; let exp_ty: exp => Typ.t = ({ty, _}) => ty; let pat_ctx: pat => Ctx.t = ({ctx, _}) => ctx; let pat_ty: pat => Typ.t = ({ty, _}) => ty; +let pat_constraint: pat => Constraint.t = ({constraint_, _}) => constraint_; let rec status_common = (ctx: Ctx.t, mode: Mode.t, self: Self.t): status_common => diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0f7e91c410..69035e9e21 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -270,67 +270,38 @@ and uexp_to_info_map = ); | Match(scrut, rules) => let (scrut, m) = go(~mode=Syn, scrut, m); - let (ps, es) = List.split(rules); - let branch_ids = List.map(UExp.rep_id, es); - let xis = - List.map( - (pat: UPat.t): Constraint.t => { - let (patInfo, _) = - upat_to_info_map( - ~is_synswitch=true, - ~ctx, - ~ancestors, - ~mode, - pat, - m, - ); - patInfo.constraint_; - }, - ps, - ); - let (ps, m) = - map_m(go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), ps, m); - let p_ctxs = List.map(Info.pat_ctx, ps); - let (es, m) = - List.fold_left2( - ((es, m), e, ctx) => - go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), - ([], m), - es, - p_ctxs, - ); - - let type_of_exp = (rule: UExp.t): Typ.t => { - let (inf, _) = - uexp_to_info_map( - ~ctx=Builtins.ctx_init, - ~ancestors=[], - rule, - Id.Map.empty, + let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { + let (ps, es) = List.split(rules); + let branch_ids = List.map(UExp.rep_id, es); + let (ps, m) = + map_m(go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), ps, m); + let p_constraints = List.map(Info.pat_constraint, ps); + let p_ctxs = List.map(Info.pat_ctx, ps); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, ); - inf.ty; - }; - - //ruls_to_info_map was implemented but not sure where to use yet - [@warning "-26"] - let ruls_to_info_map = (rules: list(UExp.t)): list(Typ.t) => { - List.fold_left( - (acc, rule) => {List.append(acc, [type_of_exp(rule)])}, - [], - rules, + ( + es, + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)), + branch_ids, + Constraint.or_constraints(p_constraints), + m, ); }; - let final_constraint = Constraint.or_constraints(xis); + let (es, e_co_ctxs, branch_ids, final_constraint, m) = + rules_to_info_map(rules, m); let e_tys = List.map(Info.exp_ty, es); - let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); let self = Incon.is_exhaustive(final_constraint) ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => let m = utpat_to_info_map(~ctx, ~ancestors, typat, m) |> snd; From f61ab29e955b0bd7fc04d638b311857997984835 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 13:33:33 -0400 Subject: [PATCH 126/229] Fixed 0 rules bug --- src/haz3lcore/dynamics/Constraint.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index f2ed742299..90823edded 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -141,7 +141,7 @@ let unwrap_pair = let rec or_constraints = (lst: list(t)): t => switch (lst) { - | [] => failwith("should have at least one constraint") + | [] => Falsity | [xi] => xi | [xi, ...xis] => Or(xi, or_constraints(xis)) }; From 186cb1e651dfb29020b42055a5dcbf9a17d8739d Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 14:02:55 -0400 Subject: [PATCH 127/229] Init --- src/haz3lcore/statics/Info.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index a68171bc52..869a7f7a22 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -70,6 +70,7 @@ type error_exp = [@deriving (show({with_path: false}), sexp, yojson)] type error_pat = | ExpectedConstructor /* Only construtors can be applied */ + // TODO | Common(error_common); [@deriving (show({with_path: false}), sexp, yojson)] From 33c484eeea9369191910fb56c8f5ca831d9eef59 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 20:19:53 -0400 Subject: [PATCH 128/229] Added error_pat.Redundant --- src/haz3lcore/statics/Info.re | 5 +++-- src/haz3lweb/view/CursorInspector.re | 11 ++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 869a7f7a22..6708f39ffb 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -70,7 +70,7 @@ type error_exp = [@deriving (show({with_path: false}), sexp, yojson)] type error_pat = | ExpectedConstructor /* Only construtors can be applied */ - // TODO + | Redundant(option(error_pat)) | Common(error_common); [@deriving (show({with_path: false}), sexp, yojson)] @@ -301,8 +301,9 @@ let rec status_common = InHole(Inconsistent(Internal(Typ.of_source(tys)))) }; -let status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => +let rec status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => switch (mode, self) { + // TODO: | | (Syn | Ana(_), Common(self_pat)) | (SynFun, Common(IsConstructor(_) as self_pat)) => /* Little bit of a hack. Anything other than a bound ctr will, in diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 6cc2adf8f6..86db8d7aa9 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -174,9 +174,18 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; -let pat_view = (cls: Term.Cls.t, status: Info.status_pat) => +let rec pat_view = (cls: Term.Cls.t, status: Info.status_pat) => switch (status) { | InHole(ExpectedConstructor) => div_err([text("Expected a constructor")]) + | InHole(Redundant(additional_err)) => + switch (additional_err) { + | None => div_err([text("Pattern is necessarily redundant")]) + | Some(err) => + div_err([ + pat_view(cls, InHole(err)), + text("; pattern is necessarily redundant"), + ]) + } | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; From 7276a41aa5e0b5811793f35090e06075b75cc7c2 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 20:52:44 -0400 Subject: [PATCH 129/229] Added Self.pat --- src/haz3lcore/statics/Info.re | 13 ++++++++++++- src/haz3lcore/statics/Self.re | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 6708f39ffb..8674eec840 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -303,7 +303,18 @@ let rec status_common = let rec status_pat = (ctx: Ctx.t, mode: Mode.t, self: Self.pat): status_pat => switch (mode, self) { - // TODO: | + | (_, Redundant(self)) => + let additional_err = + switch (status_pat(ctx, mode, self)) { + | InHole(Common(Inconsistent(Internal(_) | Expectation(_))) as err) + | InHole(Common(NoType(_)) as err) => Some(err) + | NotInHole(_) => None + | InHole(Common(Inconsistent(WithArrow(_)))) + | InHole(ExpectedConstructor | Redundant(_)) => + // ExpectedConstructor cannot be a reason to hole-wrap the entire pattern + failwith("InHole(Redundant(impossible_err))") + }; + InHole(Redundant(additional_err)); | (Syn | Ana(_), Common(self_pat)) | (SynFun, Common(IsConstructor(_) as self_pat)) => /* Little bit of a hack. Anything other than a bound ctr will, in diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re index 684b19b01b..9f4f7d48ed 100644 --- a/src/haz3lcore/statics/Self.re +++ b/src/haz3lcore/statics/Self.re @@ -40,6 +40,7 @@ type exp = [@deriving (show({with_path: false}), sexp, yojson)] type pat = + | Redundant(pat) | Common(t); /* What the type would be if the position had been @@ -64,6 +65,7 @@ let typ_of_exp: (Ctx.t, exp) => option(Typ.t) = let typ_of_pat: (Ctx.t, pat) => option(Typ.t) = ctx => fun + | Redundant(_) => None | Common(self) => typ_of(ctx, self); /* The self of a var depends on the ctx; if the From 50193838dda12ed47415cc456cd71fd68a8e7fdc Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 23:17:02 -0400 Subject: [PATCH 130/229] Fixed Bool bug --- src/haz3lcore/dynamics/Constraint.re | 5 +++-- src/haz3lcore/statics/Statics.re | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 90823edded..704f83ca44 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -9,8 +9,8 @@ type t = | NotInt(int) | Float(float) | NotFloat(float) - | Bool(bool) - | NotBool(bool) + | Bool(bool) // Wrong + | NotBool(bool) // Wrong | String(string) | NotString(string) | And(t, t) @@ -20,6 +20,7 @@ type t = | Pair(t, t); // | Tuple(list(t)); +// Unused let rec constrains = (c: t, ty: Typ.t): bool => switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { | (Truth, _) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 69035e9e21..547e8a8913 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -402,7 +402,13 @@ and upat_to_info_map = | Int(int) => atomic(Just(Int), Constraint.Int(int)) | Float(float) => atomic(Just(Float), Constraint.Float(float)) | Triv => atomic(Just(Prod([])), Constraint.Truth) - | Bool(bool) => atomic(Just(Bool), Constraint.Bool(bool)) + | Bool(bool) => + atomic( + Just(Bool), + bool + ? Constraint.InjL(Constraint.Truth) + : Constraint.InjR(Constraint.Truth), + ) | String(string) => atomic(Just(String), Constraint.String(string)) | ListLit(ps) => let ids = List.map(UPat.rep_id, ps); From c1bc4254baa56123e1d9571a08750653eb2e95f1 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Fri, 20 Oct 2023 23:27:32 -0400 Subject: [PATCH 131/229] Reviewed Constraint.dual --- src/haz3lcore/dynamics/Constraint.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 704f83ca44..933da40b65 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -62,6 +62,7 @@ let rec dual = (c: t): t => switch (c) { | Truth => Falsity | Falsity => Truth + // The complement of an indeterministic set is still indeterministic | Hole => Hole | Int(n) => NotInt(n) | NotInt(n) => Int(n) From 643e1237898cdf52ecc073fb94abc9e9292e651a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 21 Oct 2023 11:34:42 -0400 Subject: [PATCH 132/229] Fixed String bug --- src/haz3lcore/dynamics/Incon.re | 7 ++++--- src/haz3lcore/dynamics/Sets.re | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index d52fa6662b..12e2616a40 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -89,9 +89,9 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { List.fold_left( ((string_set, not_string_list), xi: Constraint.t) => switch (xi) { - | Float(n) => (StringSet.add(n, string_set), not_string_list) - | NotFloat(n) => (string_set, [n, ...not_string_list]) - | _ => failwith("input can only be Float | NotFloat") + | String(n) => (StringSet.add(n, string_set), not_string_list) + | NotString(n) => (string_set, [n, ...not_string_list]) + | _ => failwith("input can only be String | NotString") }, (StringSet.empty, []), xis, @@ -251,6 +251,7 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => } }; +// xi_cur must not indeterminately entail xi_pre let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => is_inconsistent( ~may=false, diff --git a/src/haz3lcore/dynamics/Sets.re b/src/haz3lcore/dynamics/Sets.re index 67b6099709..5c2179da68 100644 --- a/src/haz3lcore/dynamics/Sets.re +++ b/src/haz3lcore/dynamics/Sets.re @@ -18,6 +18,6 @@ module FloatSet = module StringSet = Set.Make({ - type t = float; + type t = string; let compare = compare; }); From b3d8cce65376c4046e1ec6a1c7257f6b73f11af3 Mon Sep 17 00:00:00 2001 From: Karan Anand Date: Sat, 21 Oct 2023 14:31:06 -0400 Subject: [PATCH 133/229] Generating pattern constraints sequentially --- src/haz3lcore/statics/Statics.re | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 547e8a8913..ed8438a730 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -44,6 +44,21 @@ let map_m = (f, xs, m: Map.t) => xs, ); +let map_m_constraint = (f, xs, m: Map.t) => + List.fold_left( + ((xs, m, acc_cons), x) => + f(x, m) + |> ( + ((x, m)) => ( + xs @ [x], + m, + Constraint.or_constraints([acc_cons, Info.pat_constraint(x)]), + ) + ), + ([], m, Constraint.Falsity), + xs, + ); + let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => ids |> List.fold_left((m, id) => Id.Map.add(id, info, m), m); @@ -273,8 +288,14 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - let (ps, m) = - map_m(go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), ps, m); + [@warning "-27"] + //final_cons is the final constraint generated during the mapping process + let (ps, m, final_cons) = + map_m_constraint( + go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), + ps, + m, + ); let p_constraints = List.map(Info.pat_constraint, ps); let p_ctxs = List.map(Info.pat_ctx, ps); let (es, m) = From 5b311bcda07961f80a6420aea7e00f2e2be4b463 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 00:28:42 -0400 Subject: [PATCH 134/229] Incon code simplification I --- src/haz3lcore/dynamics/Constraint.re | 11 ++++ src/haz3lcore/dynamics/Incon.re | 88 ++++++++++------------------ 2 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 933da40b65..88e2b90de8 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -126,6 +126,17 @@ let rec falsify = (c: t): t => | Pair(c1, c2) => Pair(falsify(c1), falsify(c2)) }; +// temporary name +let is_injL = + fun + | InjL(_) => true + | _ => false; + +let is_injR = + fun + | InjR(_) => true + | _ => false; + let unwrapL = fun | InjL(c) => c diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 12e2616a40..237c4b63c5 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -115,60 +115,47 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => switch (xis) { | [] => false + | _ + when + List.exists(Constraint.is_injL, xis) + && List.exists(Constraint.is_injR, xis) => + true | [xi, ...xis'] => switch (xi) { | Truth => is_inconsistent(~may, xis') | Falsity => true - | Hole => may ? true : is_inconsistent(~may, xis') + | Hole => assert(false) // Impossible | And(xi1, xi2) => is_inconsistent(~may, [xi1, xi2, ...xis']) | Or(xi1, xi2) => is_inconsistent(~may, [xi1, ...xis']) && is_inconsistent(~may, [xi2, ...xis']) | InjL(_) => - if (List.exists( - fun - | Constraint.InjR(_) => true - | _ => false, - xis, - )) { - true; - } else { - switch ( - List.partition( - fun - | Constraint.InjL(_) => true - | _ => false, - xis, - ) - ) { - | (injLs, []) => - let unwrap = List.map(Constraint.unwrapL, injLs); - is_inconsistent(~may, unwrap); - | (injLs, other) => is_inconsistent(~may, other @ injLs) - }; + switch ( + List.partition( + fun + | Constraint.InjL(_) => true + | _ => false, + xis, + ) + ) { + | (injLs, []) => + let unwrap = List.map(Constraint.unwrapL, injLs); + is_inconsistent(~may, unwrap); + | (injLs, other) => is_inconsistent(~may, other @ injLs) } | InjR(_) => - if (List.exists( - fun - | Constraint.InjL(_) => true - | _ => false, - xis, - )) { - true; - } else { - switch ( - List.partition( - fun - | Constraint.InjR(_) => true - | _ => false, - xis, - ) - ) { - | (injRs, []) => - let unwrap = List.map(Constraint.unwrapR, injRs); - is_inconsistent(~may, unwrap); - | (injRs, other) => is_inconsistent(~may, other @ injRs) - }; + switch ( + List.partition( + fun + | Constraint.InjR(_) => true + | _ => false, + xis, + ) + ) { + | (injRs, []) => + let unwrap = List.map(Constraint.unwrapR, injRs); + is_inconsistent(~may, unwrap); + | (injRs, other) => is_inconsistent(~may, other @ injRs) } | Int(_) | NotInt(_) => @@ -199,19 +186,7 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => | (fs, other) => is_inconsistent(~may, other @ fs) } | Bool(_) - | NotBool(_) => - switch ( - List.partition( - fun - | Constraint.Bool(_) - | NotBool(_) => true - | _ => false, - xis, - ) - ) { - | (fs, []) => is_inconsistent_bool(fs) - | (fs, other) => is_inconsistent(~may, other @ fs) - } + | NotBool(_) => assert(false) // Unused | String(_) | NotString(_) => switch ( @@ -251,7 +226,6 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => } }; -// xi_cur must not indeterminately entail xi_pre let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => is_inconsistent( ~may=false, From 9ec5fe030e19bc70b8b51736fb22777b525f9a16 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 00:58:53 -0400 Subject: [PATCH 135/229] Applied Constraint.is_inl and Constraint.is_inr --- src/haz3lcore/dynamics/Constraint.re | 4 ++-- src/haz3lcore/dynamics/Incon.re | 22 ++++------------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 88e2b90de8..14984c575c 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -127,12 +127,12 @@ let rec falsify = (c: t): t => }; // temporary name -let is_injL = +let is_inl = fun | InjL(_) => true | _ => false; -let is_injR = +let is_inr = fun | InjR(_) => true | _ => false; diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 237c4b63c5..dfe2698fe1 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -117,8 +117,8 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => | [] => false | _ when - List.exists(Constraint.is_injL, xis) - && List.exists(Constraint.is_injR, xis) => + List.exists(Constraint.is_inl, xis) + && List.exists(Constraint.is_inr, xis) => true | [xi, ...xis'] => switch (xi) { @@ -130,28 +130,14 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => is_inconsistent(~may, [xi1, ...xis']) && is_inconsistent(~may, [xi2, ...xis']) | InjL(_) => - switch ( - List.partition( - fun - | Constraint.InjL(_) => true - | _ => false, - xis, - ) - ) { + switch (List.partition(Constraint.is_inl, xis)) { | (injLs, []) => let unwrap = List.map(Constraint.unwrapL, injLs); is_inconsistent(~may, unwrap); | (injLs, other) => is_inconsistent(~may, other @ injLs) } | InjR(_) => - switch ( - List.partition( - fun - | Constraint.InjR(_) => true - | _ => false, - xis, - ) - ) { + switch (List.partition(Constraint.is_inr, xis)) { | (injRs, []) => let unwrap = List.map(Constraint.unwrapR, injRs); is_inconsistent(~may, unwrap); From 7561afdf7edbbf0cfd2ca6895df1a8f71a6a694c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 01:19:37 -0400 Subject: [PATCH 136/229] Incon code simplification II --- src/haz3lcore/dynamics/Incon.re | 49 ++------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index dfe2698fe1..a38c0cb964 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -16,12 +16,7 @@ let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { true; } else { List.fold_left( - (incon, n) => - if (incon) { - incon; - } else { - IntSet.mem(n, int_set); - }, + (incon, n) => incon || IntSet.mem(n, int_set), false, not_int_list, ); @@ -44,46 +39,13 @@ let is_inconsistent_float = (xis: list(Constraint.t)): bool => { true; } else { List.fold_left( - (incon, n) => - if (incon) { - incon; - } else { - FloatSet.mem(n, float_set); - }, + (incon, n) => incon || FloatSet.mem(n, float_set), false, not_float_list, ); }; }; -let is_inconsistent_bool = (xis: list(Constraint.t)): bool => { - let (bool_set, not_bool_list) = - List.fold_left( - ((bool_set, not_bool_list), xi: Constraint.t) => - switch (xi) { - | Bool(b) => (BoolSet.add(b, bool_set), not_bool_list) - | NotBool(b) => (bool_set, [b, ...not_bool_list]) - | _ => failwith("input can only be Bool | NotBool") - }, - (BoolSet.empty, []), - xis, - ); - if (BoolSet.cardinal(bool_set) > 1) { - true; - } else { - List.fold_left( - (incon, b) => - if (incon) { - incon; - } else { - BoolSet.mem(b, bool_set); - }, - false, - not_bool_list, - ); - }; -}; - let is_inconsistent_string = (xis: list(Constraint.t)): bool => { let (string_set, not_string_list) = List.fold_left( @@ -100,12 +62,7 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { true; } else { List.fold_left( - (incon, n) => - if (incon) { - incon; - } else { - StringSet.mem(n, string_set); - }, + (incon, n) => incon || StringSet.mem(n, string_set), false, not_string_list, ); From 65c8b1458f580427d437c2dc8da3dd91bf83d70c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 01:25:31 -0400 Subject: [PATCH 137/229] Deleted the argument ~may in Incon.re --- src/haz3lcore/dynamics/Incon.re | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index a38c0cb964..0136380ba3 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -69,7 +69,7 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { }; }; -let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => +let rec is_inconsistent = (xis: list(Constraint.t)): bool => switch (xis) { | [] => false | _ @@ -79,26 +79,25 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => true | [xi, ...xis'] => switch (xi) { - | Truth => is_inconsistent(~may, xis') + | Truth => is_inconsistent(xis') | Falsity => true | Hole => assert(false) // Impossible - | And(xi1, xi2) => is_inconsistent(~may, [xi1, xi2, ...xis']) + | And(xi1, xi2) => is_inconsistent([xi1, xi2, ...xis']) | Or(xi1, xi2) => - is_inconsistent(~may, [xi1, ...xis']) - && is_inconsistent(~may, [xi2, ...xis']) + is_inconsistent([xi1, ...xis']) && is_inconsistent([xi2, ...xis']) | InjL(_) => switch (List.partition(Constraint.is_inl, xis)) { | (injLs, []) => let unwrap = List.map(Constraint.unwrapL, injLs); - is_inconsistent(~may, unwrap); - | (injLs, other) => is_inconsistent(~may, other @ injLs) + is_inconsistent(unwrap); + | (injLs, other) => is_inconsistent(other @ injLs) } | InjR(_) => switch (List.partition(Constraint.is_inr, xis)) { | (injRs, []) => let unwrap = List.map(Constraint.unwrapR, injRs); - is_inconsistent(~may, unwrap); - | (injRs, other) => is_inconsistent(~may, other @ injRs) + is_inconsistent(unwrap); + | (injRs, other) => is_inconsistent(other @ injRs) } | Int(_) | NotInt(_) => @@ -112,7 +111,7 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => ) ) { | (ns, []) => is_inconsistent_nums(ns) - | (ns, other) => is_inconsistent(~may, other @ ns) + | (ns, other) => is_inconsistent(other @ ns) } | Float(_) | NotFloat(_) => @@ -126,7 +125,7 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => ) ) { | (fs, []) => is_inconsistent_float(fs) - | (fs, other) => is_inconsistent(~may, other @ fs) + | (fs, other) => is_inconsistent(other @ fs) } | Bool(_) | NotBool(_) => assert(false) // Unused @@ -142,7 +141,7 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => ) ) { | (fs, []) => is_inconsistent_string(fs) - | (fs, other) => is_inconsistent(~may, other @ fs) + | (fs, other) => is_inconsistent(other @ fs) } | Pair(_, _) => switch ( @@ -163,17 +162,16 @@ let rec is_inconsistent = (~may=false, xis: list(Constraint.t)): bool => ([], []), pairs, ); - is_inconsistent(~may, xisL) || is_inconsistent(~may, xisR); - | (pairs, other) => is_inconsistent(~may, other @ pairs) + is_inconsistent(xisL) || is_inconsistent(xisR); + | (pairs, other) => is_inconsistent(other @ pairs) } } }; let is_redundant = (xi_cur: Constraint.t, xi_pre: Constraint.t): bool => is_inconsistent( - ~may=false, Constraint.[And(truify(xi_cur), dual(falsify(xi_pre)))], ); let is_exhaustive = (xi: Constraint.t): bool => - is_inconsistent(~may=true, Constraint.[dual(truify(xi))]); + is_inconsistent(Constraint.[dual(truify(xi))]); From 3c8e0f690f8263626c75013ca5562db2392e4700 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 02:10:59 -0400 Subject: [PATCH 138/229] Incon code simplification III --- src/haz3lcore/dynamics/Incon.re | 66 +++++++++------------------------ 1 file changed, 18 insertions(+), 48 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 0136380ba3..0d23a8309b 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -1,6 +1,6 @@ open Sets; -let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { +let is_inconsistent_int = (xis: list(Constraint.t)): bool => { let (int_set, not_int_list) = List.fold_left( ((int_set, not_int_list), xi: Constraint.t) => @@ -12,15 +12,8 @@ let is_inconsistent_nums = (xis: list(Constraint.t)): bool => { (IntSet.empty, []), xis, ); - if (IntSet.cardinal(int_set) > 1) { - true; - } else { - List.fold_left( - (incon, n) => incon || IntSet.mem(n, int_set), - false, - not_int_list, - ); - }; + IntSet.cardinal(int_set) > 1 + || List.exists(IntSet.mem(_, int_set), not_int_list); }; let is_inconsistent_float = (xis: list(Constraint.t)): bool => { @@ -35,15 +28,8 @@ let is_inconsistent_float = (xis: list(Constraint.t)): bool => { (FloatSet.empty, []), xis, ); - if (FloatSet.cardinal(float_set) > 1) { - true; - } else { - List.fold_left( - (incon, n) => incon || FloatSet.mem(n, float_set), - false, - not_float_list, - ); - }; + FloatSet.cardinal(float_set) > 1 + || List.exists(FloatSet.mem(_, float_set), not_float_list); }; let is_inconsistent_string = (xis: list(Constraint.t)): bool => { @@ -58,15 +44,8 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { (StringSet.empty, []), xis, ); - if (StringSet.cardinal(string_set) > 1) { - true; - } else { - List.fold_left( - (incon, n) => incon || StringSet.mem(n, string_set), - false, - not_string_list, - ); - }; + StringSet.cardinal(string_set) > 1 + || List.exists(StringSet.mem(_, string_set), not_string_list); }; let rec is_inconsistent = (xis: list(Constraint.t)): bool => @@ -88,16 +67,14 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => | InjL(_) => switch (List.partition(Constraint.is_inl, xis)) { | (injLs, []) => - let unwrap = List.map(Constraint.unwrapL, injLs); - is_inconsistent(unwrap); - | (injLs, other) => is_inconsistent(other @ injLs) + injLs |> List.map(Constraint.unwrapL) |> is_inconsistent + | (injLs, others) => is_inconsistent(others @ injLs) } | InjR(_) => switch (List.partition(Constraint.is_inr, xis)) { | (injRs, []) => - let unwrap = List.map(Constraint.unwrapR, injRs); - is_inconsistent(unwrap); - | (injRs, other) => is_inconsistent(other @ injRs) + injRs |> List.map(Constraint.unwrapR) |> is_inconsistent + | (injRs, others) => is_inconsistent(others @ injRs) } | Int(_) | NotInt(_) => @@ -110,8 +87,8 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => xis, ) ) { - | (ns, []) => is_inconsistent_nums(ns) - | (ns, other) => is_inconsistent(other @ ns) + | (ns, []) => is_inconsistent_int(ns) + | (ns, others) => is_inconsistent(others @ ns) } | Float(_) | NotFloat(_) => @@ -125,7 +102,7 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => ) ) { | (fs, []) => is_inconsistent_float(fs) - | (fs, other) => is_inconsistent(other @ fs) + | (fs, others) => is_inconsistent(others @ fs) } | Bool(_) | NotBool(_) => assert(false) // Unused @@ -140,8 +117,8 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => xis, ) ) { - | (fs, []) => is_inconsistent_string(fs) - | (fs, other) => is_inconsistent(other @ fs) + | (ss, []) => is_inconsistent_string(ss) + | (ss, others) => is_inconsistent(others @ ss) } | Pair(_, _) => switch ( @@ -154,16 +131,9 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => ) { | (pairs, []) => let (xisL, xisR) = - List.fold_left( - ((xisL, xisR), pair) => { - let (xiL, xiR) = Constraint.unwrap_pair(pair); - ([xiL, ...xisL], [xiR, ...xisR]); - }, - ([], []), - pairs, - ); + pairs |> List.map(Constraint.unwrap_pair) |> List.split; is_inconsistent(xisL) || is_inconsistent(xisR); - | (pairs, other) => is_inconsistent(other @ pairs) + | (pairs, others) => is_inconsistent(others @ pairs) } } }; From f31485b28d3a5b7b982422dc213ecc439f193a31 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 02:14:55 -0400 Subject: [PATCH 139/229] Deleted Constraint.Bool/NotBool --- src/haz3lcore/dynamics/Constraint.re | 10 ---------- src/haz3lcore/dynamics/Incon.re | 2 -- 2 files changed, 12 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 14984c575c..156546957a 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -9,8 +9,6 @@ type t = | NotInt(int) | Float(float) | NotFloat(float) - | Bool(bool) // Wrong - | NotBool(bool) // Wrong | String(string) | NotString(string) | And(t, t) @@ -30,8 +28,6 @@ let rec constrains = (c: t, ty: Typ.t): bool => | (Int(_) | NotInt(_), _) => false | (Float(_) | NotFloat(_), Float) => true | (Float(_) | NotFloat(_), _) => false - | (Bool(_) | NotBool(_), Bool) => true - | (Bool(_) | NotBool(_), _) => false | (String(_) | NotString(_), String) => true | (String(_) | NotString(_), _) => false | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) @@ -68,8 +64,6 @@ let rec dual = (c: t): t => | NotInt(n) => Int(n) | Float(n) => NotFloat(n) | NotFloat(n) => Float(n) - | Bool(b) => NotBool(b) - | NotBool(b) => Bool(b) | String(n) => NotString(n) | NotString(n) => String(n) | And(c1, c2) => Or(dual(c1), dual(c2)) @@ -94,8 +88,6 @@ let rec truify = (c: t): t => | NotInt(_) | Float(_) | NotFloat(_) - | Bool(_) - | NotBool(_) | String(_) | NotString(_) => c | And(c1, c2) => And(truify(c1), truify(c2)) @@ -115,8 +107,6 @@ let rec falsify = (c: t): t => | NotInt(_) | Float(_) | NotFloat(_) - | Bool(_) - | NotBool(_) | String(_) | NotString(_) => c | And(c1, c2) => And(falsify(c1), falsify(c2)) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 0d23a8309b..15497f7b91 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -104,8 +104,6 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => | (fs, []) => is_inconsistent_float(fs) | (fs, others) => is_inconsistent(others @ fs) } - | Bool(_) - | NotBool(_) => assert(false) // Unused | String(_) | NotString(_) => switch ( From 0d5f5b55774b2ba692aa794ff12f0a268a9eb801 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 02:34:14 -0400 Subject: [PATCH 140/229] Inlined map_m_constraint Co-Authored-By: Karan Anand <58492510+karananand01@users.noreply.github.com> --- src/haz3lcore/statics/Statics.re | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ed8438a730..cc917e42e5 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -44,21 +44,6 @@ let map_m = (f, xs, m: Map.t) => xs, ); -let map_m_constraint = (f, xs, m: Map.t) => - List.fold_left( - ((xs, m, acc_cons), x) => - f(x, m) - |> ( - ((x, m)) => ( - xs @ [x], - m, - Constraint.or_constraints([acc_cons, Info.pat_constraint(x)]), - ) - ), - ([], m, Constraint.Falsity), - xs, - ); - let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => ids |> List.fold_left((m, id) => Id.Map.add(id, info, m), m); @@ -291,10 +276,18 @@ and uexp_to_info_map = [@warning "-27"] //final_cons is the final constraint generated during the mapping process let (ps, m, final_cons) = - map_m_constraint( - go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty)), + List.fold_left( + ((xs, m, acc_cons), x) => + go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty), x, m) + |> ( + ((x, m)) => ( + xs @ [x], + m, + Constraint.Or(acc_cons, Info.pat_constraint(x)), + ) + ), + ([], m, Constraint.Falsity), ps, - m, ); let p_constraints = List.map(Info.pat_constraint, ps); let p_ctxs = List.map(Info.pat_ctx, ps); From 5361ce690aeb044eddee6fbe3f65c0731921e6a0 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 22 Oct 2023 03:59:29 -0400 Subject: [PATCH 141/229] Adjusted info for redundant patterns --- src/haz3lcore/statics/Info.re | 3 ++- src/haz3lcore/statics/Statics.re | 42 +++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 8674eec840..cf692f8f71 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -460,8 +460,9 @@ let fixed_constraint_pat = (ctx, mode: Mode.t, self: Self.pat, constraint_: Constraint.t) : Constraint.t => switch (status_pat(ctx, mode, self)) { - | InHole(_) => Constraint.Hole + | InHole(Redundant(None)) | NotInHole(_) => constraint_ + | InHole(_) => Constraint.Hole }; let fixed_typ_exp = (ctx, mode: Mode.t, self: Self.exp): Typ.t => diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index cc917e42e5..840f2a5292 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -273,23 +273,37 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - [@warning "-27"] - //final_cons is the final constraint generated during the mapping process - let (ps, m, final_cons) = + let (ps, m, final_constraint) = List.fold_left( - ((xs, m, acc_cons), x) => - go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty), x, m) - |> ( - ((x, m)) => ( - xs @ [x], - m, - Constraint.Or(acc_cons, Info.pat_constraint(x)), - ) - ), + ((ps, m, acc_constraint), p) => { + let (p, m) = + go_pat(~is_synswitch=false, ~mode=Mode.Ana(scrut.ty), p, m); + let p_constraint = Info.pat_constraint(p); + if (!Incon.is_redundant(p_constraint, acc_constraint)) { + (ps @ [p], m, Constraint.Or(p_constraint, acc_constraint)); + } else { + let info = + Info.derived_pat( + ~upat=p.term, + ~ctx=p.ctx, + ~mode=p.mode, + ~ancestors=p.ancestors, + ~self=Redundant(p.self), + // Mark patterns as redundant at the top level + // because redundancy doesn't make sense in a smaller context + ~constraint_=p_constraint, + ); + ( + ps @ [info], + // Override the info for the single upat + add_info(p.term.ids, InfoPat(info), m), + acc_constraint // Redundant patterns are ignored + ); + }; + }, ([], m, Constraint.Falsity), ps, ); - let p_constraints = List.map(Info.pat_constraint, ps); let p_ctxs = List.map(Info.pat_ctx, ps); let (es, m) = List.fold_left2( @@ -303,7 +317,7 @@ and uexp_to_info_map = es, List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)), branch_ids, - Constraint.or_constraints(p_constraints), + final_constraint, m, ); }; From e9a8896e1dc0ae270ec10066c074c82ecd685f69 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang <108375845+pigumar1@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:42:02 -0400 Subject: [PATCH 142/229] Revert InvalidOperationError.re --- src/haz3lcore/dynamics/InvalidOperationError.re | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/haz3lcore/dynamics/InvalidOperationError.re b/src/haz3lcore/dynamics/InvalidOperationError.re index 3a6e31c35f..ce8c94e888 100644 --- a/src/haz3lcore/dynamics/InvalidOperationError.re +++ b/src/haz3lcore/dynamics/InvalidOperationError.re @@ -5,8 +5,6 @@ type t = | DivideByZero | NegativeExponent | OutOfFuel - // | InvalidIntOfString - // | InvalidFloatOfString | InvalidProjection; let err_msg = (err: t): string => @@ -16,7 +14,5 @@ let err_msg = (err: t): string => | DivideByZero => "Error: Divide by Zero" | NegativeExponent => "Error: Negative Exponent in Integer Exponentiation (Consider using **.)" | OutOfFuel => "Error: Out of Fuel" - // | InvalidIntOfString => "Error: Invalid String to Int Conversion" - // | InvalidFloatOfString => "Error: Invalid String to Float Conversion" | InvalidProjection => "Error: Invalid Projection" }; From 3c4e58db465c8038b9385a9ded0d37b90957044f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Mon, 23 Oct 2023 00:11:02 -0400 Subject: [PATCH 143/229] Made redundancy not a runtime error --- src/haz3lcore/dynamics/Elaborator.re | 7 +++++++ src/haz3lcore/statics/Info.re | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 126dee2e21..28d271688a 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -284,6 +284,13 @@ let rec dhexp_of_uexp = and dhpat_of_upat = (m: Statics.Map.t, upat: Term.UPat.t): option(DHPat.t) => { switch (Id.Map.find_opt(Term.UPat.rep_id(upat), m)) { | Some(InfoPat({mode, self, ctx, _})) => + // NOTE: for the current implementation, redundancy is considered a static error + // but not a runtime error. + let self = + switch (self) { + | Redundant(self) => self + | _ => self + }; let err_status = Info.status_pat(ctx, mode, self); let maybe_reason: option(ErrStatus.HoleReason.t) = switch (err_status) { diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index cf692f8f71..69bbb1c6db 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -450,11 +450,18 @@ let fixed_typ_ok: ok_pat => Typ.t = | Ana(Consistent({join, _})) => join | Ana(InternallyInconsistent({ana, _})) => ana; -let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => +let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => { + // TODO: get rid of unwrapping (probably by changing the implementation of error_exp.Redundant) + let self = + switch (self) { + | Redundant(self) => self + | _ => self + }; switch (status_pat(ctx, mode, self)) { | InHole(_) => Unknown(Internal) | NotInHole(ok) => fixed_typ_ok(ok) }; +}; let fixed_constraint_pat = (ctx, mode: Mode.t, self: Self.pat, constraint_: Constraint.t) From cd03276cb320285b358f2e6fbbb2a6457708f3c4 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang <108375845+pigumar1@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:58:26 -0400 Subject: [PATCH 144/229] Allowed redundant patterns to have types in Self.typ_of_pat --- src/haz3lcore/statics/Self.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Self.re b/src/haz3lcore/statics/Self.re index 9f4f7d48ed..3b4e1b7cc8 100644 --- a/src/haz3lcore/statics/Self.re +++ b/src/haz3lcore/statics/Self.re @@ -62,10 +62,10 @@ let typ_of_exp: (Ctx.t, exp) => option(Typ.t) = | InexhaustiveMatch(_) => None | Common(self) => typ_of(ctx, self); -let typ_of_pat: (Ctx.t, pat) => option(Typ.t) = +let rec typ_of_pat: (Ctx.t, pat) => option(Typ.t) = ctx => fun - | Redundant(_) => None + | Redundant(pat) => typ_of_pat(ctx, pat) | Common(self) => typ_of(ctx, self); /* The self of a var depends on the ctx; if the From dd9aed58a11c02f61f7be985563c6aedcd11100c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang <108375845+pigumar1@users.noreply.github.com> Date: Mon, 23 Oct 2023 13:22:22 -0400 Subject: [PATCH 145/229] Having applications of non-ctrs and unbounded ctrs emit Falsity --- src/haz3lcore/dynamics/Constraint.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 933da40b65..241db9ef92 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -162,11 +162,11 @@ let of_ap = (ctx, ctr: option(Constructor.t), arg: t): t => switch (ctr) { | Some(name) => switch (Ctx.lookup_ctr(ctx, name)) { - | None => Hole // TODO: review + | None => Falsity // TODO: review | Some({num_variants, nth, _}) => arg |> ctr_of_nth_variant(num_variants, nth) } - | None => Hole // TODO: review + | None => Falsity // TODO: review }; let of_ctr = (ctx, name) => of_ap(ctx, Some(name), Truth); From 8403af349c9eb62699c36e750a047a1481759042 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Wed, 25 Oct 2023 21:29:17 -0400 Subject: [PATCH 146/229] Fixed multiple-error-holes bug --- src/haz3lweb/view/Deco.re | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/haz3lweb/view/Deco.re b/src/haz3lweb/view/Deco.re index d349e91c92..1de355ce09 100644 --- a/src/haz3lweb/view/Deco.re +++ b/src/haz3lweb/view/Deco.re @@ -300,6 +300,11 @@ module Deco = // faster infomap traversal let err_holes = (_z: Zipper.t) => { + let is_rep = (id: Id.t) => + switch (Id.Map.find_opt(id, M.terms)) { + | None => false + | Some(term) => id == Term.rep_id(term) + }; Id.Map.fold( (id, info, acc) => /* Because of artefacts in Maketerm ID handling, @@ -309,7 +314,12 @@ module Deco = * when iterating over the info_map should have no * effect, beyond supressing the resulting Not_found exs */ switch (Id.Map.find_opt(id, M.term_ranges)) { - | Some(_) when Info.is_error(info) => [ + /* Without filtering out non-rep ids, there will be + * multiple error holes wrapping around a case expression + * or a list literal that has at least one comma, since the + * rules of case expressions and the inner commas of list + * literals are technically different forms */ + | Some(_) when is_rep(id) && Info.is_error(info) => [ term_highlight(~clss=["err-hole"], id), ...acc, ] From 5d8a674926469534a9cdf846885829aa2f5b9743 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang <108375845+pigumar1@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:22:31 -0400 Subject: [PATCH 147/229] =?UTF-8?q?Removed=20=E2=80=9Cnecessarily=E2=80=9D?= =?UTF-8?q?=20in=20the=20user-facing=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/haz3lweb/view/CursorInspector.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 6cc2adf8f6..cf181113fb 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -163,11 +163,11 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => div_err([code_err(name), text("not found")]) | InHole(InexhaustiveMatch(additional_err)) => switch (additional_err) { - | None => div_err([text("Case expression is necessarily inexhaustive")]) + | None => div_err([text("Case expression is inexhaustive")]) | Some(err) => div_err([ exp_view(Exp(Match), InHole(err)), - text("; case expression is necessarily inexhaustive"), + text("; case expression is inexhaustive"), ]) } | InHole(Common(error)) => div_err(common_err_view(cls, error)) From df04be9cdde305c4a498d1cbfcd9b68f884b7e6b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang <108375845+pigumar1@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:25:38 -0400 Subject: [PATCH 148/229] =?UTF-8?q?=20Removed=20=E2=80=9Cnecessarily?= =?UTF-8?q?=E2=80=9D=20in=20the=20user-facing=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/haz3lweb/view/CursorInspector.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 78fd8b9922..b586e6dfe2 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -179,11 +179,11 @@ let rec pat_view = (cls: Term.Cls.t, status: Info.status_pat) => | InHole(ExpectedConstructor) => div_err([text("Expected a constructor")]) | InHole(Redundant(additional_err)) => switch (additional_err) { - | None => div_err([text("Pattern is necessarily redundant")]) + | None => div_err([text("Pattern is redundant")]) | Some(err) => div_err([ pat_view(cls, InHole(err)), - text("; pattern is necessarily redundant"), + text("; pattern is redundant"), ]) } | InHole(Common(error)) => div_err(common_err_view(cls, error)) From ed3138ebdb66a5ae61042f5b9eb680fbcd5e071b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 26 Oct 2023 12:31:31 -0400 Subject: [PATCH 149/229] Reformatted --- src/haz3lweb/view/CursorInspector.re | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index b586e6dfe2..027b0320c4 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -181,10 +181,7 @@ let rec pat_view = (cls: Term.Cls.t, status: Info.status_pat) => switch (additional_err) { | None => div_err([text("Pattern is redundant")]) | Some(err) => - div_err([ - pat_view(cls, InHole(err)), - text("; pattern is redundant"), - ]) + div_err([pat_view(cls, InHole(err)), text("; pattern is redundant")]) } | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) From 32230474b2ff3039561cf9081a7910293813788b Mon Sep 17 00:00:00 2001 From: disconcision Date: Thu, 26 Oct 2023 15:26:06 -0400 Subject: [PATCH 150/229] fix dhexp error hole formatting --- src/haz3lweb/www/style.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/haz3lweb/www/style.css b/src/haz3lweb/www/style.css index 6a646dc172..a8ea7bcae0 100644 --- a/src/haz3lweb/www/style.css +++ b/src/haz3lweb/www/style.css @@ -1517,6 +1517,7 @@ svg.expandable path { } .result { + padding-top: 0.1em; min-height: 1.6em; width: 100%; overflow-y: hidden; @@ -1548,8 +1549,6 @@ svg.expandable path { .DHCode svg.err-hole { fill: #d001; - transform: scaleY(0.8); - /* HACK(andrew) */ stroke-dasharray: 1, 1; stroke: var(--err-color); stroke-width: 1.2px; From 717fe511b1d54974a524c540b1f66955ae7f5592 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 18 Nov 2023 16:10:33 -0500 Subject: [PATCH 151/229] Small adjustments --- src/haz3lcore/dynamics/Constraint.re | 6 ++---- src/haz3lcore/dynamics/Incon.re | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 29bb54b9d3..f5e6c7b256 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -16,7 +16,6 @@ type t = | InjL(t) | InjR(t) | Pair(t, t); -// | Tuple(list(t)); // Unused let rec constrains = (c: t, ty: Typ.t): bool => @@ -58,14 +57,13 @@ let rec dual = (c: t): t => switch (c) { | Truth => Falsity | Falsity => Truth - // The complement of an indeterministic set is still indeterministic | Hole => Hole | Int(n) => NotInt(n) | NotInt(n) => Int(n) | Float(n) => NotFloat(n) | NotFloat(n) => Float(n) - | String(n) => NotString(n) - | NotString(n) => String(n) + | String(s) => NotString(s) + | NotString(s) => String(s) | And(c1, c2) => Or(dual(c1), dual(c2)) | Or(c1, c2) => And(dual(c1), dual(c2)) | InjL(c1) => Or(InjL(dual(c1)), InjR(Truth)) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 15497f7b91..460c3c14f6 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -37,8 +37,8 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { List.fold_left( ((string_set, not_string_list), xi: Constraint.t) => switch (xi) { - | String(n) => (StringSet.add(n, string_set), not_string_list) - | NotString(n) => (string_set, [n, ...not_string_list]) + | String(s) => (StringSet.add(n, string_set), not_string_list) + | NotString(s) => (string_set, [n, ...not_string_list]) | _ => failwith("input can only be String | NotString") }, (StringSet.empty, []), From 9a8a8ec6b1c568f7db19b9ac1766337a77916f34 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 18 Nov 2023 16:11:55 -0500 Subject: [PATCH 152/229] Removed Constraint.constrains --- src/haz3lcore/dynamics/Constraint.re | 36 ---------------------------- 1 file changed, 36 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index f5e6c7b256..6348456c19 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -17,42 +17,6 @@ type t = | InjR(t) | Pair(t, t); -// Unused -let rec constrains = (c: t, ty: Typ.t): bool => - switch (c, Typ.weak_head_normalize(Builtins.ctx_init, ty)) { - | (Truth, _) - | (Falsity, _) - | (Hole, _) => true - | (Int(_) | NotInt(_), Int) => true - | (Int(_) | NotInt(_), _) => false - | (Float(_) | NotFloat(_), Float) => true - | (Float(_) | NotFloat(_), _) => false - | (String(_) | NotString(_), String) => true - | (String(_) | NotString(_), _) => false - | (And(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) - | (Or(c1, c2), _) => constrains(c1, ty) && constrains(c2, ty) - // Treates sum as if it is left associative - | (InjL(c1), Sum(map)) => - switch (List.hd(map)) { - | (_, Some(ty1)) => constrains(c1, ty1) - | _ => false - } - | (InjL(_), _) => false - | (InjR(c2), Sum(map)) => - switch (List.tl(map)) { - | [] => false - | [(_, Some(ty2))] => constrains(c2, ty2) - | map' => constrains(c2, Sum(map')) - } - | (InjR(_), _) => false - | (Pair(c1, c2), Prod([ty_hd, ...ty_tl])) => - constrains(c1, ty_hd) && constrains(c2, Prod(ty_tl)) - | (Pair(_), _) => false - // | (Tuple(cs), Prod(tys)) when List.length(cs) == List.length(tys) => - // List.for_all2(constrains, cs, tys) - // | (Tuple(_), _) => false - }; - let rec dual = (c: t): t => switch (c) { | Truth => Falsity From 079bef956099c22d80681b1e5151408d5b71e85a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 18 Nov 2023 16:17:02 -0500 Subject: [PATCH 153/229] Compile --- src/haz3lcore/dynamics/Incon.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 460c3c14f6..68cd54f48c 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -37,8 +37,8 @@ let is_inconsistent_string = (xis: list(Constraint.t)): bool => { List.fold_left( ((string_set, not_string_list), xi: Constraint.t) => switch (xi) { - | String(s) => (StringSet.add(n, string_set), not_string_list) - | NotString(s) => (string_set, [n, ...not_string_list]) + | String(s) => (StringSet.add(s, string_set), not_string_list) + | NotString(s) => (string_set, [s, ...not_string_list]) | _ => failwith("input can only be String | NotString") }, (StringSet.empty, []), From 24a2c2e5b9e38fb41553dd0740d8f2514eee2319 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 18 Nov 2023 16:27:15 -0500 Subject: [PATCH 154/229] Replaced is_inl/r with is_injL/R --- src/haz3lcore/dynamics/Constraint.re | 6 ++---- src/haz3lcore/dynamics/Incon.re | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 6348456c19..6d45857893 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -37,7 +37,6 @@ let rec dual = (c: t): t => Pair(c1, dual(c2)), Or(Pair(dual(c1), c2), Pair(dual(c1), dual(c2))), ) - // | Tuple(cs) => // TODO }; /** substitute Truth for Hole */ @@ -78,13 +77,12 @@ let rec falsify = (c: t): t => | Pair(c1, c2) => Pair(falsify(c1), falsify(c2)) }; -// temporary name -let is_inl = +let is_injL = fun | InjL(_) => true | _ => false; -let is_inr = +let is_injR = fun | InjR(_) => true | _ => false; diff --git a/src/haz3lcore/dynamics/Incon.re b/src/haz3lcore/dynamics/Incon.re index 68cd54f48c..6f5c6af13f 100644 --- a/src/haz3lcore/dynamics/Incon.re +++ b/src/haz3lcore/dynamics/Incon.re @@ -53,8 +53,8 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => | [] => false | _ when - List.exists(Constraint.is_inl, xis) - && List.exists(Constraint.is_inr, xis) => + List.exists(Constraint.is_injL, xis) + && List.exists(Constraint.is_injR, xis) => true | [xi, ...xis'] => switch (xi) { @@ -65,13 +65,13 @@ let rec is_inconsistent = (xis: list(Constraint.t)): bool => | Or(xi1, xi2) => is_inconsistent([xi1, ...xis']) && is_inconsistent([xi2, ...xis']) | InjL(_) => - switch (List.partition(Constraint.is_inl, xis)) { + switch (List.partition(Constraint.is_injL, xis)) { | (injLs, []) => injLs |> List.map(Constraint.unwrapL) |> is_inconsistent | (injLs, others) => is_inconsistent(others @ injLs) } | InjR(_) => - switch (List.partition(Constraint.is_inr, xis)) { + switch (List.partition(Constraint.is_injR, xis)) { | (injRs, []) => injRs |> List.map(Constraint.unwrapR) |> is_inconsistent | (injRs, others) => is_inconsistent(others @ injRs) From e1bbb70ceed73016df3ac92f0b7c68db24aa6d22 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sat, 18 Nov 2023 20:56:01 -0500 Subject: [PATCH 155/229] New structure for non-exhaustive case matches --- src/haz3lcore/statics/Statics.re | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index f1d304c726..6a3c700ce4 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -299,9 +299,13 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); + let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = - Incon.is_exhaustive(final_constraint) - ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + if (!is_exhaustive) { + let dual_constraint = Constraint.dual(Constraint.or_constraints(final_constraint)); + // TODO + } add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From 5b72b62b3169f2ad8682b6ce0282fb4c1c41b2a0 Mon Sep 17 00:00:00 2001 From: DavidFangWJ <2500097466@qq.com> Date: Sat, 18 Nov 2023 21:55:09 -0500 Subject: [PATCH 156/229] Fix bug from last commit. --- src/haz3lcore/statics/Statics.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6a3c700ce4..2a03c1e705 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -303,7 +303,7 @@ and uexp_to_info_map = let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); if (!is_exhaustive) { - let dual_constraint = Constraint.dual(Constraint.or_constraints(final_constraint)); + let dual_constraint = Constraint.dual(final_constraint); // TODO } From 2ebb54a335f958896dd95a597d4c73e11004994f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 21 Nov 2023 19:06:29 -0500 Subject: [PATCH 157/229] init --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2a03c1e705..bb23968c0d 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -302,10 +302,10 @@ and uexp_to_info_map = let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - if (!is_exhaustive) { - let dual_constraint = Constraint.dual(final_constraint); - // TODO - } + // if (!is_exhaustive) { + // let dual_constraint = Constraint.dual(final_constraint); + // // TODO + // } add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From 714a54f7d81592c0d1031978e66e6f7502555210 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 13 Dec 2023 01:08:09 -0500 Subject: [PATCH 158/229] Fix error with missing casts from inappropriate synthesis joining. --- src/haz3lcore/statics/Info.re | 13 +++++++++---- src/haz3lcore/statics/TypBase.re | 8 +++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 374a3164e2..10c1090bd4 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -303,13 +303,18 @@ let rec status_common = | None => InHole(Inconsistent(WithArrow(ty))) } | (Just(ty), SynTypFun) => - /* Use ty first to preserve name if it exists. */ - switch (Typ.join_fix(ctx, ty, Forall("?", Unknown(Internal)))) { + switch (Typ.join_fix(ctx, Forall("?", Unknown(Internal)), ty)) { | Some(_) => NotInHole(Syn(ty)) | None => InHole(Inconsistent(WithArrow(ty))) } | (Just(syn), Ana(ana)) => - switch (Typ.join_fix(ctx, syn, ana)) { + switch ( + Typ.join_fix( + ctx, + ana, + syn /* Note: the ordering of ana, syn matters */ + ) + ) { | None => InHole(Inconsistent(Expectation({syn, ana}))) | Some(join) => NotInHole(Ana(Consistent({ana, syn, join}))) } @@ -328,7 +333,7 @@ let rec status_common = | (IsMulti, _) => NotInHole(Syn(Unknown(Internal))) | (NoJoin(wrap, tys), Ana(ana)) => let syn: Typ.t = Self.join_of(wrap, Unknown(Internal)); - switch (Typ.join_fix(ctx, syn, ana)) { + switch (Typ.join_fix(ctx, ana, syn)) { | None => InHole(Inconsistent(Expectation({ana, syn}))) | Some(_) => NotInHole( diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index a340dc1e3c..72c8f4fab9 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -277,17 +277,19 @@ module rec Typ: { | (Rec(x1, ty1), Rec(x2, ty2)) => let ctx = Ctx.extend_dummy_tvar(ctx, x1); let+ ty_body = - join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); + join(~resolve, ~fix, ctx, subst(Var(x2), x1, ty1), ty2); Rec(x1, ty_body); | (Forall(x1, ty1), Forall(x2, ty2)) => let ctx = Ctx.extend_dummy_tvar(ctx, x1); let+ ty_body = - join(~resolve, ~fix, ctx, ty1, subst(Var(x1), x2, ty2)); + join(~resolve, ~fix, ctx, subst(Var(x2), x1, ty1), ty2); Forall(x1, ty_body); /* Note for above: there is no danger of free variable capture as subst itself performs capture avoiding substitution. However this may generate internal type variable names that in corner cases can - be exposed to the user. */ + be exposed to the user. We preserve the variable name of the + second type to preserve synthesized type variable names, which + come from user annotations. */ | (Rec(_), _) => None | (Forall(_), _) => None | (Int, Int) => Some(Int) From 3e9e158584127e3057998033f5820ef5eecc49ff Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 20:12:46 -0500 Subject: [PATCH 159/229] Changed argument from ctx to mode in of_ap and of_ctr --- src/haz3lcore/dynamics/Constraint.re | 36 +++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 6d45857893..df220f6903 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -119,15 +119,39 @@ let rec ctr_of_nth_variant = (num_variants, nth): (t => t) => xi => InjR(xi |> ctr_of_nth_variant(num_variants - 1, nth - 1)); }; -let of_ap = (ctx, ctr: option(Constructor.t), arg: t): t => +let of_ap = (mode, ctr: option(Constructor.t), arg: t): t => switch (ctr) { | Some(name) => - switch (Ctx.lookup_ctr(ctx, name)) { - | None => Falsity // TODO: review - | Some({num_variants, nth, _}) => - arg |> ctr_of_nth_variant(num_variants, nth) + switch (mode) { + | Mode.Ana(Sum(map)) => + let num_variants = List.length(map); + let map_sorted = + List.sort( + ((ctr1, _), (ctr2, _)) => String.compare(ctr1, ctr2), + map, + ); + // available for OCaml 5.1 + // switch (List.find_index((ctr, _) => ctr == name, map_sorted)) { + // } + let (nth_opt, _) = + List.fold_left( + ((_, index), (ctr, _)): (option(int), int) => + (ctr == name ? Some(index) : None, index + 1), + (None, 0), + map_sorted, + ); + switch (nth_opt) { + | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) + | None => Falsity // TODO: review + }; + | _ => Falsity // TODO: review } + // switch (Ctx.lookup_ctr(ctx, name)) { + // | None => Falsity // TODO: review + // | Some({num_variants, nth, _}) => + // arg |> ctr_of_nth_variant(num_variants, nth) + // } | None => Falsity // TODO: review }; -let of_ctr = (ctx, name) => of_ap(ctx, Some(name), Truth); +let of_ctr = (mode, name) => of_ap(mode, Some(name), Truth); From 4241f409e3b2ea8fa055dd147cb9be33d7267e6a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 20:24:12 -0500 Subject: [PATCH 160/229] weak_head_normalized --- src/haz3lcore/dynamics/Constraint.re | 50 +++++++++++++++------------- src/haz3lcore/statics/Statics.re | 4 +-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index df220f6903..9b6562b7ee 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -119,31 +119,35 @@ let rec ctr_of_nth_variant = (num_variants, nth): (t => t) => xi => InjR(xi |> ctr_of_nth_variant(num_variants - 1, nth - 1)); }; -let of_ap = (mode, ctr: option(Constructor.t), arg: t): t => +let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => switch (ctr) { | Some(name) => switch (mode) { - | Mode.Ana(Sum(map)) => - let num_variants = List.length(map); - let map_sorted = - List.sort( - ((ctr1, _), (ctr2, _)) => String.compare(ctr1, ctr2), - map, - ); - // available for OCaml 5.1 - // switch (List.find_index((ctr, _) => ctr == name, map_sorted)) { - // } - let (nth_opt, _) = - List.fold_left( - ((_, index), (ctr, _)): (option(int), int) => - (ctr == name ? Some(index) : None, index + 1), - (None, 0), - map_sorted, - ); - switch (nth_opt) { - | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) - | None => Falsity // TODO: review - }; + | Mode.Ana(ty) => + switch (Typ.weak_head_normalize(ctx, ty)) { + | Sum(map) => + let num_variants = List.length(map); + let map_sorted = + List.sort( + ((ctr1, _), (ctr2, _)) => String.compare(ctr1, ctr2), + map, + ); + // available for OCaml 5.1 + // switch (List.find_index((ctr, _) => ctr == name, map_sorted)) { + // } + let (nth_opt, _) = + List.fold_left( + ((_, index), (ctr, _)): (option(int), int) => + (ctr == name ? Some(index) : None, index + 1), + (None, 0), + map_sorted, + ); + switch (nth_opt) { + | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) + | None => Falsity // TODO: review + }; + | _ => Falsity // TODO: review + } | _ => Falsity // TODO: review } // switch (Ctx.lookup_ctr(ctx, name)) { @@ -154,4 +158,4 @@ let of_ap = (mode, ctr: option(Constructor.t), arg: t): t => | None => Falsity // TODO: review }; -let of_ctr = (mode, name) => of_ap(mode, Some(name), Truth); +let of_ctr = (ctx, mode, name) => of_ap(ctx, mode, Some(name), Truth); diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index bb23968c0d..8eab3761f2 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -475,7 +475,7 @@ and upat_to_info_map = let (p, m) = go(~ctx, ~mode, p, m); add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => - atomic(Self.of_ctr(ctx, ctr), Constraint.of_ctr(ctx, ctr)) + atomic(Self.of_ctr(ctx, ctr), Constraint.of_ctr(ctx, mode, ctr)) | Ap(fn, arg) => let ctr = UPat.ctr_name(fn); let fn_mode = Mode.of_ap(ctx, mode, ctr); @@ -485,7 +485,7 @@ and upat_to_info_map = add( ~self=Just(ty_out), ~ctx=arg.ctx, - ~constraint_=Constraint.of_ap(ctx, ctr, arg.constraint_), + ~constraint_=Constraint.of_ap(ctx, mode, ctr, arg.constraint_), m, ); | TypeAnn(p, ann) => From 63f3f397e2e4141208f01370da961bcf26c77e8b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 20:50:55 -0500 Subject: [PATCH 161/229] Bug fix --- src/haz3lcore/dynamics/Constraint.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 9b6562b7ee..f927cf3bbf 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -137,8 +137,8 @@ let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => // } let (nth_opt, _) = List.fold_left( - ((_, index), (ctr, _)): (option(int), int) => - (ctr == name ? Some(index) : None, index + 1), + ((nth_opt, index), (ctr, _)): (option(int), int) => + (ctr == name ? Some(index) : nth_opt, index + 1), (None, 0), map_sorted, ); From a6b03f625d3cdc8ad5e86cf2de52be14d3bd1920 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 20:54:46 -0500 Subject: [PATCH 162/229] Clean --- src/haz3lcore/statics/Statics.re | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 8eab3761f2..e7f21b1025 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -302,10 +302,6 @@ and uexp_to_info_map = let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - // if (!is_exhaustive) { - // let dual_constraint = Constraint.dual(final_constraint); - // // TODO - // } add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From 8c308adddb541bbab2f359de788f60abb53c862e Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 22:48:49 -0500 Subject: [PATCH 163/229] Added CtorMap.nth --- src/haz3lcore/dynamics/Constraint.re | 19 ++----------------- src/haz3lcore/statics/ConstructorMap.re | 9 +++++++++ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index f927cf3bbf..bfcad35dbd 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -126,23 +126,8 @@ let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => | Mode.Ana(ty) => switch (Typ.weak_head_normalize(ctx, ty)) { | Sum(map) => - let num_variants = List.length(map); - let map_sorted = - List.sort( - ((ctr1, _), (ctr2, _)) => String.compare(ctr1, ctr2), - map, - ); - // available for OCaml 5.1 - // switch (List.find_index((ctr, _) => ctr == name, map_sorted)) { - // } - let (nth_opt, _) = - List.fold_left( - ((nth_opt, index), (ctr, _)): (option(int), int) => - (ctr == name ? Some(index) : nth_opt, index + 1), - (None, 0), - map_sorted, - ); - switch (nth_opt) { + let num_variants = ConstructorMap.cardinal(map); + switch (ConstructorMap.nth(name, map)) { | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) | None => Falsity // TODO: review }; diff --git a/src/haz3lcore/statics/ConstructorMap.re b/src/haz3lcore/statics/ConstructorMap.re index c9ff0667dc..a3e1def0ee 100644 --- a/src/haz3lcore/statics/ConstructorMap.re +++ b/src/haz3lcore/statics/ConstructorMap.re @@ -99,3 +99,12 @@ let rec is_ground = (is_ground_value: 'a => bool, map: t('a)): bool => | [(_, head), ...tail] => is_ground_value(head) && tail |> is_ground(is_ground_value) }; + +let nth = (ctr: Constructor.t, map: t('a)): option(int) => { + // TODO: used List.find_index instead, which is available for OCaml 5.1 + let ctrs_sorted = map |> sort |> ctrs_of; + List.find_opt( + nth => List.nth(ctrs_sorted, nth) == ctr, + List.init(List.length(ctrs_sorted), Fun.id), + ); +}; From a69e23aa6fbf943507c9440c1a2363ac375e2c1d Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 16 Dec 2023 22:56:13 -0500 Subject: [PATCH 164/229] Clean --- src/haz3lcore/dynamics/Constraint.re | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index bfcad35dbd..8174f6e816 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -135,11 +135,6 @@ let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => } | _ => Falsity // TODO: review } - // switch (Ctx.lookup_ctr(ctx, name)) { - // | None => Falsity // TODO: review - // | Some({num_variants, nth, _}) => - // arg |> ctr_of_nth_variant(num_variants, nth) - // } | None => Falsity // TODO: review }; From 4f510c1f484d8b1333d40af240dc999a4ef5b107 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Mon, 18 Dec 2023 12:58:55 -0500 Subject: [PATCH 165/229] Update ConstructorMap.re --- src/haz3lcore/statics/ConstructorMap.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/ConstructorMap.re b/src/haz3lcore/statics/ConstructorMap.re index a3e1def0ee..f871173adc 100644 --- a/src/haz3lcore/statics/ConstructorMap.re +++ b/src/haz3lcore/statics/ConstructorMap.re @@ -101,7 +101,7 @@ let rec is_ground = (is_ground_value: 'a => bool, map: t('a)): bool => }; let nth = (ctr: Constructor.t, map: t('a)): option(int) => { - // TODO: used List.find_index instead, which is available for OCaml 5.1 + // TODO: use List.find_index instead, which is available for OCaml 5.1 let ctrs_sorted = map |> sort |> ctrs_of; List.find_opt( nth => List.nth(ctrs_sorted, nth) == ctr, From 606abc4569caa7575535edbc59548ca8bdc3af6c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 23 Dec 2023 23:17:02 -0500 Subject: [PATCH 166/229] InexhaustiveMatch(option(error_exp)) => (option(error_common)) --- src/haz3lcore/dynamics/Elaborator.re | 4 +--- src/haz3lcore/statics/Info.re | 4 ++-- src/haz3lcore/statics/Statics.re | 4 ---- src/haz3lweb/view/CursorInspector.re | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 2e7963a7de..4b7cf2aee5 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -269,9 +269,7 @@ let rec dhexp_of_uexp = let d = DHExp.Case(d_scrut, d_rules, 0); switch (err_status) { | InHole(Common(Inconsistent(Internal(_)))) - | InHole( - InexhaustiveMatch(Some(Common(Inconsistent(Internal(_))))), - ) => + | InHole(InexhaustiveMatch(Some(Inconsistent(Internal(_))))) => DHExp.InconsistentBranches(id, 0, d) | _ => ConsistentCase(d) }; diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index a68171bc52..68189a2a53 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -64,7 +64,7 @@ type error_common = [@deriving (show({with_path: false}), sexp, yojson)] type error_exp = | FreeVariable(Var.t) /* Unbound variable (not in typing context) */ - | InexhaustiveMatch(option(error_exp)) + | InexhaustiveMatch(option(error_common)) | Common(error_common); [@deriving (show({with_path: false}), sexp, yojson)] @@ -327,7 +327,7 @@ let rec status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => | (InexhaustiveMatch(self), _) => let additional_err = switch (status_exp(ctx, mode, self)) { - | InHole(Common(Inconsistent(Internal(_))) as inconsistent_err) => + | InHole(Common(Inconsistent(Internal(_)) as inconsistent_err)) => Some(inconsistent_err) | NotInHole(_) | InHole(Common(Inconsistent(Expectation(_) | WithArrow(_)))) => None /* Type checking should fail and these errors would be nullified */ diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2a03c1e705..6b1536ed08 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -302,10 +302,6 @@ and uexp_to_info_map = let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - if (!is_exhaustive) { - let dual_constraint = Constraint.dual(final_constraint); - // TODO - } add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index cf181113fb..f0bb32b32c 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -166,7 +166,7 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => | None => div_err([text("Case expression is inexhaustive")]) | Some(err) => div_err([ - exp_view(Exp(Match), InHole(err)), + exp_view(Exp(Match), InHole(Common(err))), text("; case expression is inexhaustive"), ]) } From 60d4aa0728052fb0a320e9bb6c0950284072cb61 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 23 Dec 2023 23:47:42 -0500 Subject: [PATCH 167/229] reformatted --- src/haz3lcore/statics/Info.re | 16 ++++++++++-- src/haz3lcore/statics/Statics.re | 43 +++++++++++++++++++------------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 7a9eea3929..84d8e21622 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -497,12 +497,24 @@ let derived_exp = /* Add derivable attributes for pattern terms */ let derived_pat = - (~upat: UPat.t, ~ctx, ~co_ctx, ~mode, ~ancestors, ~self, ~constraint_): pat => { + (~upat: UPat.t, ~ctx, ~co_ctx, ~mode, ~ancestors, ~self, ~constraint_) + : pat => { let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); let constraint_ = fixed_constraint_pat(ctx, mode, self, constraint_); - {cls, self, mode, ty, status, ctx, co_ctx, ancestors, term: upat, constraint_}; + { + cls, + self, + mode, + ty, + status, + ctx, + co_ctx, + ancestors, + term: upat, + constraint_, + }; }; /* Add derivable attributes for types */ diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 551bf9b32e..f1961a9f9d 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -305,7 +305,15 @@ and uexp_to_info_map = let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); let (ps', m) = - map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty, ~mode=Mode.Ana(scrut.ty)), ps, m); + map_m( + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Mode.Ana(scrut.ty), + ), + ps, + m, + ); let p_constraints = List.map(Info.pat_constraint, ps'); let p_ctxs = List.map(Info.pat_ctx, ps'); let (es, m) = @@ -316,9 +324,24 @@ and uexp_to_info_map = es, p_ctxs, ); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + /* Add co-ctxs to patterns */ + let (_, m) = + map_m( + ((p, co_ctx)) => + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(scrut.ty), + p, + ), + List.combine(ps, e_co_ctxs), + m, + ); ( es, - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)), + e_co_ctxs, branch_ids, Constraint.or_constraints(p_constraints), m, @@ -327,26 +350,12 @@ and uexp_to_info_map = let (es, e_co_ctxs, branch_ids, final_constraint, m) = rules_to_info_map(rules, m); let e_tys = List.map(Info.exp_ty, es); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - /* Add co-ctxs to patterns */ - let (_, m) = - map_m( - ((p, co_ctx)) => - go_pat(~is_synswitch=false, ~co_ctx, ~mode=Mode.Ana(scrut.ty), p), - List.combine(ps, e_co_ctxs), - m, - ); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - add'( - ~self, - ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), - m, - ); + add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => let m = utpat_to_info_map(~ctx, ~ancestors, typat, m) |> snd; switch (typat.term) { From c81ee313fc8190086aa6058124e26eb5666b8247 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Mon, 25 Dec 2023 09:20:34 -0500 Subject: [PATCH 168/229] Update Statics.re --- src/haz3lcore/statics/Statics.re | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0febe2ceaf..3a92c49722 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -308,7 +308,13 @@ and uexp_to_info_map = List.fold_left( ((ps', m, acc_constraint), p) => { let (p, m) = - go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty, ~mode=Mode.Ana(scrut.ty), p, m); + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Mode.Ana(scrut.ty), + p, + m, + ); let p_constraint = Info.pat_constraint(p); if (!Incon.is_redundant(p_constraint, acc_constraint)) { (ps' @ [p], m, Constraint.Or(p_constraint, acc_constraint)); @@ -317,6 +323,7 @@ and uexp_to_info_map = Info.derived_pat( ~upat=p.term, ~ctx=p.ctx, + ~co_ctx=p.co_ctx, ~mode=p.mode, ~ancestors=p.ancestors, ~self=Redundant(p.self), @@ -359,13 +366,7 @@ and uexp_to_info_map = List.combine(ps, e_co_ctxs), m, ); - ( - es, - e_co_ctxs, - branch_ids, - final_constraint, - m, - ); + (es, e_co_ctxs, branch_ids, final_constraint, m); }; let (es, e_co_ctxs, branch_ids, final_constraint, m) = rules_to_info_map(rules, m); From 5d79b718c67a55d0382ad11b08ae52b27e4f871e Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 4 Jan 2024 06:51:50 -0500 Subject: [PATCH 169/229] compilable --- src/haz3lcore/statics/Statics.re | 40 ++++++++++++++++---------------- src/haz3lcore/statics/Term.re | 1 + 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 5c3f0d3958..e1a740b26d 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -292,28 +292,28 @@ and uexp_to_info_map = if (!is_recursive(ctx, p, def, p_syn.ty)) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m); let (p_ana', _) = - go_pat( - ~is_synswitch=false, - ~co_ctx=CoCtx.empty, - ~mode=Ana(def.ty), - p, - m, - ); + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Ana(def.ty), + p, + m, + ); (def, p_ana', m); } else { - let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m); + let (def_base, _) = + go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m); /* Analyze pattern to incorporate def type into ctx */ - let (p_ana', _) = - go_pat( - ~is_synswitch=false, - ~co_ctx=CoCtx.empty, - ~mode=Ana(def_base.ty), - p, - m, - ); - let def_ctx = p_ana.ctx; - let (def_base2, _) = - go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); + let (p_ana', _) = + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Ana(def_base.ty), + p, + m, + ); + let def_ctx = p_ana'.ctx; + let (def_base2, _) = go'(~ctx=def_ctx, ~mode=Ana(p_syn.ty), def, m); let ana_ty_fn = ((ty_fn1, ty_fn2), ty_p) => { ty_p == Typ.Unknown(SynSwitch) && !Typ.eq(ty_fn1, ty_fn2) ? ty_fn1 : ty_p; @@ -329,7 +329,7 @@ and uexp_to_info_map = let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(ana), def, m); (def, p_ana', m); }; - let (body, m) = go'(~ctx=p_ana.ctx, ~mode, body, m); + let (body, m) = go'(~ctx=p_ana'.ctx, ~mode, body, m); /* add co_ctx to pattern */ let (p_ana, m) = go_pat( diff --git a/src/haz3lcore/statics/Term.re b/src/haz3lcore/statics/Term.re index 84ce4a19cc..c3dea4da09 100644 --- a/src/haz3lcore/statics/Term.re +++ b/src/haz3lcore/statics/Term.re @@ -640,6 +640,7 @@ module UExp = { | TyAlias(_) | Ap(_) | DeferredAp(_) + | Pipeline(_) | If(_) | Seq(_) | Test(_) From 6e5ced9d9b08aff338e236a1fcaf1286e0a4ebe8 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 4 Jan 2024 07:41:56 -0500 Subject: [PATCH 170/229] Consistent context --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index e1a740b26d..3af530404e 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -288,7 +288,7 @@ and uexp_to_info_map = | Let(p, def, body) => let (p_syn, _) = go_pat(~is_synswitch=true, ~co_ctx=CoCtx.empty, ~mode=Syn, p, m); - let (def, p_ana', m) = + let (def, p_ana', m, ty_p_ana) = if (!is_recursive(ctx, p, def, p_syn.ty)) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m); let (p_ana', _) = @@ -299,7 +299,7 @@ and uexp_to_info_map = p, m, ); - (def, p_ana', m); + (def, p_ana', m, def.ty); } else { let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m); @@ -327,7 +327,7 @@ and uexp_to_info_map = | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) }; let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(ana), def, m); - (def, p_ana', m); + (def, p_ana', m, def_base.ty); }; let (body, m) = go'(~ctx=p_ana'.ctx, ~mode, body, m); /* add co_ctx to pattern */ @@ -335,7 +335,7 @@ and uexp_to_info_map = go_pat( ~is_synswitch=false, ~co_ctx=body.co_ctx, - ~mode=Ana(def.ty), + ~mode=Ana(ty_p_ana), p, m, ); From 368f9296c5253461f14f9d16b4d69eacf52a00ec Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 4 Jan 2024 07:56:40 -0500 Subject: [PATCH 171/229] - code duplication I --- src/haz3lcore/statics/Statics.re | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 3af530404e..2a788c9a1c 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -291,24 +291,26 @@ and uexp_to_info_map = let (def, p_ana', m, ty_p_ana) = if (!is_recursive(ctx, p, def, p_syn.ty)) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m); + let ty_p_ana = def.ty; let (p_ana', _) = go_pat( ~is_synswitch=false, ~co_ctx=CoCtx.empty, - ~mode=Ana(def.ty), + ~mode=Ana(ty_p_ana), p, m, ); - (def, p_ana', m, def.ty); + (def, p_ana', m, ty_p_ana); } else { let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m); + let ty_p_ana = def_base.ty; /* Analyze pattern to incorporate def type into ctx */ let (p_ana', _) = go_pat( ~is_synswitch=false, ~co_ctx=CoCtx.empty, - ~mode=Ana(def_base.ty), + ~mode=Ana(ty_p_ana), p, m, ); @@ -327,7 +329,7 @@ and uexp_to_info_map = | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) }; let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(ana), def, m); - (def, p_ana', m, def_base.ty); + (def, p_ana', m, ty_p_ana); }; let (body, m) = go'(~ctx=p_ana'.ctx, ~mode, body, m); /* add co_ctx to pattern */ From 60282aeabb311a7740e19513d5e4fe38e0ea8b43 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 4 Jan 2024 08:11:17 -0500 Subject: [PATCH 172/229] + readability --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2a788c9a1c..872d4d0995 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -288,7 +288,7 @@ and uexp_to_info_map = | Let(p, def, body) => let (p_syn, _) = go_pat(~is_synswitch=true, ~co_ctx=CoCtx.empty, ~mode=Syn, p, m); - let (def, p_ana', m, ty_p_ana) = + let (def, p_ana_ctx, m, ty_p_ana) = if (!is_recursive(ctx, p, def, p_syn.ty)) { let (def, m) = go(~mode=Ana(p_syn.ty), def, m); let ty_p_ana = def.ty; @@ -300,7 +300,7 @@ and uexp_to_info_map = p, m, ); - (def, p_ana', m, ty_p_ana); + (def, p_ana'.ctx, m, ty_p_ana); } else { let (def_base, _) = go'(~ctx=p_syn.ctx, ~mode=Ana(p_syn.ty), def, m); @@ -329,9 +329,9 @@ and uexp_to_info_map = | ((ty_fn1, ty_fn2), ty_p) => ana_ty_fn((ty_fn1, ty_fn2), ty_p) }; let (def, m) = go'(~ctx=def_ctx, ~mode=Ana(ana), def, m); - (def, p_ana', m, ty_p_ana); + (def, def_ctx, m, ty_p_ana); }; - let (body, m) = go'(~ctx=p_ana'.ctx, ~mode, body, m); + let (body, m) = go'(~ctx=p_ana_ctx, ~mode, body, m); /* add co_ctx to pattern */ let (p_ana, m) = go_pat( From 010674d3a1570b817751c2cf4b3c606586f5b27f Mon Sep 17 00:00:00 2001 From: Cyrus Omar Date: Fri, 5 Jan 2024 16:47:57 -0500 Subject: [PATCH 173/229] regenerate Init.ml --- src/haz3lweb/Init.ml | 2162 +++++++++++++++++++++++++----------------- 1 file changed, 1281 insertions(+), 881 deletions(-) diff --git a/src/haz3lweb/Init.ml b/src/haz3lweb/Init.ml index 4824678929..22e485ee2c 100644 --- a/src/haz3lweb/Init.ml +++ b/src/haz3lweb/Init.ml @@ -13898,1183 +13898,1583 @@ let startup : PersistentData.t = ( "Polymorphism", { zipper = - "((selection((focus \ - Left)(content())))(backpack())(relatives((siblings(((Tile((id \ - 4778)(label(ex1))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 4779)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4781)(content(Whitespace\" \"))))(Tile((id \ - 4788)(label(ex2))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 4789)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4791)(content(Whitespace\" \")))))((Tile((id \ - 4794)(label(ex3))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 4795)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4797)(content(Whitespace\" \"))))(Tile((id \ - 4800)(label(ex4))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 4801)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4803)(content(Whitespace\" \"))))(Tile((id \ - 4806)(label(ex5))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))(ancestors((((id \ - 4808)(label(\"(\"\")\"))(mold((out \ - Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ - Convex)(sort \ - Exp))))))(shards((0)(1)))(children(()())))(((Secondary((id \ - 1497)(content(Comment\"# Polymorphism #\"))))(Secondary((id \ - 1465)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1544)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1675)(content(Comment\"# We can take types as parameters to \ - type functions, #\"))))(Secondary((id \ - 1676)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1722)(content(Comment\"# and use them in annoatations in the \ - body: #\"))))(Secondary((id \ - 1466)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1502)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 1503)(content(Whitespace\" \"))))(Tile((id \ - 1506)(label(id))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1507)(content(Whitespace\" \")))))((Secondary((id \ - 1508)(content(Whitespace\" \"))))(Tile((id 1516)(label(typfun \ + "((selection((focus Left)(content())(mode \ + Normal)))(backpack())(relatives((siblings(((Secondary((id \ + ce06e01f-9b12-4ea1-8549-c5615ca7e52a)(content(Comment\"# \ + Polymorphism #\"))))(Secondary((id \ + 3b3f93ba-ca3c-4c1b-8346-2d68f5504958)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + abf1a875-4891-4386-8c1c-a77ad171a596)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + e8268e68-25db-4119-aaf2-c1e01ab024a0)(content(Comment\"# We \ + can take types as parameters to type functions, \ + #\"))))(Secondary((id \ + 70f57795-15c2-4826-b2d4-b1c2414b09fc)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 28bfb176-1ada-450a-9a2e-9ee4f68b9271)(content(Comment\"# and \ + use them in annoatations in the body: #\"))))(Secondary((id \ + 6c16f965-ddc2-4208-8161-9d17a4f71e84)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + dbc1d50f-0873-4a56-becd-184560be6a16)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 3265ecf6-f14c-4851-87bd-29b1c48ad60d)(content(Whitespace\" \ + \"))))(Tile((id \ + 2f057ddc-b7b4-4a90-8772-0f54a9e6a0f1)(label(id))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 9e9a0675-cf88-464e-a5b2-22ec197d871a)(content(Whitespace\" \ + \")))))((Secondary((id \ + 7c246b01-e879-4704-ab40-1ad600b6a05d)(content(Whitespace\" \ + \"))))(Tile((id \ + 357bc39e-7763-4d16-856a-30f2fdb89cd2)(label(typfun \ ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 1517)(content(Whitespace\" \ - \"))))(Tile((id 1518)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + f9f6be49-c063-4799-a630-a15c13dc2416)(content(Whitespace\" \ + \"))))(Tile((id \ + d45a8f80-0658-42a7-bff7-6bfbf36e910d)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 1520)(content(Whitespace\" \")))))))))(Secondary((id \ - 1522)(content(Whitespace\" \"))))(Tile((id 1527)(label(fun \ + 9f37693a-1d0d-4720-a547-0bde3a0cf043)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 0f5c9f28-98cf-4704-be01-3789b89325ad)(content(Whitespace\" \ + \"))))(Tile((id \ + c41ee313-ae0d-46e3-8763-3c0003823bf6)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 1528)(content(Whitespace\" \ - \"))))(Tile((id 1529)(label(x))(mold((out \ + 1))(children(((Secondary((id \ + 5a50ead3-2382-4702-8edc-82df727a9f98)(content(Whitespace\" \ + \"))))(Tile((id \ + 95012d29-d892-46f6-9d41-9d5b6a1991ea)(label(x))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 1531)(content(Whitespace\" \"))))(Tile((id \ - 1532)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1533)(content(Whitespace\" \"))))(Tile((id \ - 1534)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 8134e2f9-624a-43ff-9e7e-f4f2fb3c44db)(content(Whitespace\" \ + \"))))(Tile((id \ + e9602009-d959-44c3-bae1-2fcca11436e0)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 1536)(content(Whitespace\" \")))))))))(Secondary((id \ - 1538)(content(Whitespace\" \"))))(Tile((id \ - 1539)(label(x))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1543)(content(Whitespace\" \")))))))))(Secondary((id \ - 1467)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1723)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1761)(content(Comment\"# Such functions are applied like so: \ - #\"))))(Secondary((id \ - 1468)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4680)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4681)(content(Whitespace\" \"))))(Tile((id \ - 4686)(label(ex1))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 4688)(content(Whitespace\" \")))))((Secondary((id \ - 4689)(content(Whitespace\" \"))))(Tile((id \ - 4685)(label(id))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 1766)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 1770)(label(Int))(mold((out \ + d8b777e0-ebea-423b-99cd-6777245529d4)(content(Whitespace\" \ + \"))))(Tile((id \ + 1e025399-f3a3-40e9-b623-4269d2b4ee01)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 89d852f5-e16c-4b7c-af4b-064b73a7d0b0)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 56b281c4-857e-4223-b818-b33e503e6340)(content(Whitespace\" \ + \"))))(Tile((id \ + fc41c74e-bd60-4cf6-8400-aa6cd0b485d2)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + b4b1ea56-6958-44fc-89bd-b6f22e6bade3)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 5c77f088-a1f3-4ba8-b7ef-efe73f27f855)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + d7c28f98-90c1-46ca-9827-7fb78625c981)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + a979ad79-2705-4ca1-9cf2-cccfec5e0086)(content(Comment\"# Such \ + functions are applied like so: #\"))))(Secondary((id \ + 5c84aefa-4652-4c4c-89ff-f05f4da85b58)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 2e888173-4ece-4010-a674-13a32957493e)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 32c1835b-c27f-4ccf-be61-a270b6e9c5ba)(content(Whitespace\" \ + \"))))(Tile((id \ + 1c2ef7e4-4439-4110-976e-41a1e8ff3d6b)(label(ex1))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 859ef193-f93b-4ae5-b070-4731bf77bc97)(content(Whitespace\" \ + \")))))((Secondary((id \ + ddb1f2b6-3fe6-4079-a75d-dcaebe48bc6f)(content(Whitespace\" \ + \"))))(Tile((id \ + 8439b029-0b7c-47cb-9867-c4c16ed4e733)(label(id))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + c5fe892a-4d64-4346-95bd-056a11c3f7ad)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 7079f97d-6950-4fd4-b76e-f6924cd0ed7e)(label(Int))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2088)(label(\"(\"\")\"))(mold((out \ + 35b79c01-e4db-4671-a26a-ec0a7933c24f)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2090)(label(1))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 83c93244-e705-4189-a816-70dd13a963ec)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 4694)(content(Whitespace\" \")))))))))(Secondary((id \ - 2023)(content(Whitespace\" \"))))(Secondary((id \ - 2085)(content(Comment\"# 1 #\"))))(Secondary((id \ - 1469)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1470)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 1878)(content(Comment\"# We can annotate the type of a type \ - function with a forall. #\"))))(Secondary((id \ - 4690)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1884)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 1885)(content(Whitespace\" \"))))(Tile((id \ - 1891)(label(const))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 1892)(content(Whitespace\" \"))))(Tile((id \ - 1893)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + 7e153b1d-8ee5-4f89-a01a-1242f0565511)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 5d0ec35e-42f0-41e6-810c-b4163164e51e)(content(Whitespace\" \ + \"))))(Secondary((id \ + fdb7e231-ff3c-4d22-a8d2-308db57999e4)(content(Comment\"# 1 \ + #\"))))(Secondary((id \ + a4b7e97a-83dd-492f-ae20-a84b2a979e30)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8c74bef9-7177-4774-89aa-805787cf673f)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 7309f6e2-2d49-45af-b7c6-0ec75a57fc2b)(content(Comment\"# We \ + can annotate the type of a type function with a forall. \ + #\"))))(Secondary((id \ + 4fda5632-5de3-4c5d-b424-bf16d704f35a)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + d1ace50b-2196-477e-aeda-e84f61901017)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + b1df318d-3e75-4630-8f19-d3cbc69bb8ee)(content(Whitespace\" \ + \"))))(Tile((id \ + 7a283681-40a7-483c-ab85-ab4916479faa)(label(const))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 69a7673c-e766-4409-852e-03c46fbbbf56)(content(Whitespace\" \ + \"))))(Tile((id \ + f5115707-8100-478a-bf56-748777fdd0c3)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 1894)(content(Whitespace\" \"))))(Tile((id 1902)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + 8bc19b04-eb77-4c2a-9668-4350e26a309d)(content(Whitespace\" \ + \"))))(Tile((id \ + a7889e83-9fe8-49ad-9bef-44e8ce448a64)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 1903)(content(Whitespace\" \ - \"))))(Tile((id 1904)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + f70ea1f6-288e-407f-8594-1736b20cce67)(content(Whitespace\" \ + \"))))(Tile((id \ + 57bed8d9-e4fb-47da-b21b-fe51fb8ee9e6)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 1914)(content(Whitespace\" \")))))))))(Secondary((id \ - 1915)(content(Whitespace\" \"))))(Tile((id 1929)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + 48e84944-6794-4ec4-9809-f8c9689fd797)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 0d8e46dc-456d-471e-9387-04fe16526ad6)(content(Whitespace\" \ + \"))))(Tile((id \ + 913ff727-11a1-4e0d-83fc-99e4de6e34f3)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 1930)(content(Whitespace\" \ - \"))))(Tile((id 1931)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + fea1b479-fbd8-4564-8a3a-93e7e3d5374b)(content(Whitespace\" \ + \"))))(Tile((id \ + d97d38b4-0e17-4bb8-b342-50937dff5896)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 1933)(content(Whitespace\" \")))))))))(Secondary((id \ - 1934)(content(Whitespace\" \"))))(Tile((id \ - 1935)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1937)(content(Whitespace\" \"))))(Tile((id \ - 1939)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1940)(content(Whitespace\" \"))))(Tile((id \ - 1941)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1943)(content(Whitespace\" \"))))(Tile((id \ - 1945)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1946)(content(Whitespace\" \"))))(Tile((id \ - 1947)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 1948)(content(Whitespace\" \")))))((Secondary((id \ - 1953)(content(Whitespace\" \"))))(Secondary((id \ - 2008)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1985)(label(typfun ->))(mold((out \ - Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + e43565a7-cbb9-45aa-ab46-5cda424a47c5)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + f9ead65c-4436-4958-898c-a7ed360b5b46)(content(Whitespace\" \ + \"))))(Tile((id \ + d6a5887c-ef92-4773-9429-919995401912)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + c5801121-b4f8-4751-bca0-6b48d487a7e6)(content(Whitespace\" \ + \"))))(Tile((id \ + a3f602fe-03e9-4b18-8c75-2699369b969e)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + b59e20fa-3d31-411e-b242-a371c0e04d03)(content(Whitespace\" \ + \"))))(Tile((id \ + 20b8244e-580b-450c-9cd2-db7cc09f9171)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 4e1ba90f-c253-4ea0-af95-d1fe89e671f6)(content(Whitespace\" \ + \"))))(Tile((id \ + 3263d74a-307a-4e5d-afc3-74a9344f4b0d)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + b3466ca7-a0f4-4aa2-a5a3-f9d1646f5033)(content(Whitespace\" \ + \"))))(Tile((id \ + 0c0fa783-0e0e-4c53-9dc6-ae591f4c9649)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + b5d049f6-643b-4a28-b9d0-8ebacdca3665)(content(Whitespace\" \ + \")))))((Secondary((id \ + 4cf96db7-3321-47be-bbc0-7c6df9c84aac)(content(Whitespace\" \ + \"))))(Secondary((id \ + 26600e0d-d6eb-40b6-9357-12b948bb85f8)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 1992686c-e8b9-4473-a1ae-d2c08a08bd83)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 1986)(content(Whitespace\" \ - \"))))(Tile((id 1989)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + a13a91a2-4077-4cc3-9f3d-574983bc9b3a)(content(Whitespace\" \ + \"))))(Tile((id \ + 4a3d43e1-6d91-48f8-941f-fc2caa196468)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 1991)(content(Whitespace\" \")))))))))(Secondary((id \ - 1993)(content(Whitespace\" \"))))(Tile((id 2001)(label(typfun \ + c26137e3-a766-4717-a269-2ba155800b8a)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 96004d3c-f493-4c07-bd6f-e717bd487554)(content(Whitespace\" \ + \"))))(Tile((id \ + ece966f5-4bfa-4f08-99ce-0a1f41c64f48)(label(typfun \ ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2002)(content(Whitespace\" \ - \"))))(Tile((id 2003)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + d9a1daf2-50e7-413b-9254-395a44586281)(content(Whitespace\" \ + \"))))(Tile((id \ + f5d75275-fa16-42f3-ad3c-6c422427c84e)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2005)(content(Whitespace\" \")))))))))(Secondary((id \ - 2007)(content(Whitespace\" \"))))(Tile((id 1957)(label(fun \ + da14e1ca-0903-4b7a-9f3d-e4d64ca651ed)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 3154b641-f630-4c85-a591-78d0ea4c6aa4)(content(Whitespace\" \ + \"))))(Tile((id \ + 4b5a8664-1772-4700-bad2-4b186a35dc5a)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 1958)(content(Whitespace\" \ - \"))))(Tile((id 1960)(label(x))(mold((out \ + 1))(children(((Secondary((id \ + 5f4ee7eb-858b-4375-8bae-ecb4688adca7)(content(Whitespace\" \ + \"))))(Tile((id \ + 4cb9bfb4-56f0-47a1-b6be-9f0a16c98e9d)(label(x))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 1961)(content(Whitespace\" \")))))))))(Secondary((id \ - 1964)(content(Whitespace\" \"))))(Tile((id 1968)(label(fun \ + 586ac15a-3af8-4b3f-99b0-0446efd5bd1c)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 5b0b25b1-b94b-45f8-9a89-3e9fe8cd1222)(content(Whitespace\" \ + \"))))(Tile((id \ + b1f6c96a-f3a7-43ea-b304-acf5a99b5d95)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 1969)(content(Whitespace\" \ - \"))))(Tile((id 1971)(label(y))(mold((out \ + 1))(children(((Secondary((id \ + 3cf3fd73-b0f4-4e68-8324-41f2c1a34db5)(content(Whitespace\" \ + \"))))(Tile((id \ + 0d9b9fbe-2609-4aeb-894a-e4d883971862)(label(y))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 1972)(content(Whitespace\" \")))))))))(Secondary((id \ - 1975)(content(Whitespace\" \"))))(Tile((id \ - 1976)(label(x))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 1977)(content(Whitespace\" \")))))))))(Secondary((id \ - 1879)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4700)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4701)(content(Whitespace\" \"))))(Tile((id \ - 4706)(label(ex2))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 4708)(content(Whitespace\" \")))))((Secondary((id \ - 4709)(content(Whitespace\" \"))))(Tile((id \ - 4705)(label(const))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2025)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2033)(label(Int))(mold((out \ + f9eacdec-ff0f-487f-b4e7-016b5eee0516)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 6dc0f10f-31b0-47f2-876c-973a06e137a6)(content(Whitespace\" \ + \"))))(Tile((id \ + 84678463-bd3d-495b-8787-5e15e9f2fb76)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 6b03a744-056f-4464-a52c-a0152aaa7165)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 378239c7-2535-4a78-8fb0-8d19433db26b)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + f686ce31-58f6-4e46-9c6c-7ee24a13619b)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 89f204f3-4bc8-4dc3-a31c-9e5d99cb1242)(content(Whitespace\" \ + \"))))(Tile((id \ + c0fd6ffc-1cb2-4d82-a6b4-798bc6251af7)(label(ex2))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 85333d35-a563-44eb-8102-a64226fc9c37)(content(Whitespace\" \ + \")))))((Secondary((id \ + 20d23ebb-f489-4103-a55f-0c6024c82896)(content(Whitespace\" \ + \"))))(Tile((id \ + 2e160900-ad22-4eb4-93f9-499a2179dc8d)(label(const))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + b64dd6ef-3a63-40ca-a9b3-85453bf6649f)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + c45a9241-5e40-42bb-9738-16984f9cced5)(label(Int))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2049)(label(@< >))(mold((out \ + 6bb9e3d9-9127-4b3e-b129-63e461202adb)(label(@< >))(mold((out \ Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2056)(label(String))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2057)(label(\"(\"\")\"))(mold((out \ + 2fa8b7dd-6963-4688-a0d3-c4ea84e886dd)(label(String))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + 137358f3-a48c-4169-a855-495f7fb95ba4)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2062)(label(2))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Tile((id \ - 2064)(label(\"(\"\")\"))(mold((out \ + 36d3b274-ad9b-4057-aa23-b0481d7c6a59)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ + 42a0f2f0-96bd-4896-960f-2c5e623c5af1)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2077)(label(\"\\\"Hello World\\\"\"))(mold((out \ - Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ - Convex)(sort \ + f282d501-c0bd-434e-873e-30b7e520cf20)(label(\"\\\"Hello \ + World\\\"\"))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 4713)(content(Whitespace\" \")))))))))(Secondary((id \ - 2079)(content(Whitespace\" \"))))(Secondary((id \ - 2083)(content(Comment\"# 2 #\"))))(Secondary((id \ - 2009)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2091)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2158)(content(Comment\"# We can go beyond rank 1 \ - polymorphism: #\"))))(Secondary((id \ - 2092)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2164)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 2165)(content(Whitespace\" \"))))(Tile((id \ - 2187)(label(apply_both))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2188)(content(Whitespace\" \"))))(Tile((id \ - 2191)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + 084144f9-6c79-422a-96d8-1ab0db271dde)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + b7c097ca-897c-4549-85b1-a3aa34bd3e48)(content(Whitespace\" \ + \"))))(Secondary((id \ + 17b2ff69-f022-4365-9611-19e153ab3510)(content(Comment\"# 2 \ + #\"))))(Secondary((id \ + 8e6a1044-6ea7-481f-b35c-f5dc277406e7)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + d9204a7d-8903-426c-a2a3-e298948f6645)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 93e3db1d-a91f-4b86-9085-4907952180d9)(content(Comment\"# We \ + can go beyond rank 1 polymorphism: #\"))))(Secondary((id \ + b3a81efa-f007-4976-8864-f0a563e7efd7)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5a144dcf-d9f2-402d-9556-b6e8ee0647e5)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + a3f3a127-a472-431b-a04d-20dfb03fee37)(content(Whitespace\" \ + \"))))(Tile((id \ + 7560359f-5145-4674-9e5d-0427f75cc171)(label(apply_both))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 2b179ba5-1578-439f-8899-d72c14f7780d)(content(Whitespace\" \ + \"))))(Tile((id \ + 453fb383-28b8-466a-ba99-063b848e02c2)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2218)(content(Whitespace\" \"))))(Tile((id 2227)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + 462a9b5f-e582-4d33-bbfa-791e557df360)(content(Whitespace\" \ + \"))))(Tile((id \ + 6c464286-72b3-49ad-b83f-571c66c1ade6)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 2228)(content(Whitespace\" \ - \"))))(Tile((id 2229)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + 4885ff9c-656c-4cac-94d3-9946c87758d1)(content(Whitespace\" \ + \"))))(Tile((id \ + b1ef3819-7e49-4952-9b4d-4553df2c1b22)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2231)(content(Whitespace\" \")))))))))(Secondary((id \ - 2232)(content(Whitespace\" \"))))(Tile((id 2240)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + 699dc9bb-69ee-4f0d-8eb8-4d08ca395ac0)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + fb4c51ac-dd80-4b42-b18a-3460c39ba250)(content(Whitespace\" \ + \"))))(Tile((id \ + a3a5af75-2734-473b-a402-3339b5a5aed3)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 2241)(content(Whitespace\" \ - \"))))(Tile((id 2242)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + 14b786ee-56d3-4868-9048-38d18607b3ed)(content(Whitespace\" \ + \"))))(Tile((id \ + e3ad6862-da04-4d40-b14d-773a130d2a4f)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2244)(content(Whitespace\" \")))))))))(Secondary((id \ - 2245)(content(Whitespace\" \"))))(Tile((id \ - 2274)(label(\"(\"\")\"))(mold((out \ + c3613e98-7473-49d7-9dcb-9e35f7d7b10d)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + e4f9136f-ecd7-497c-989d-dd9ba87a3d11)(content(Whitespace\" \ + \"))))(Tile((id \ + 9f0b4530-be66-4001-ad6d-5008ade448f5)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2282)(label(forall .))(mold((out Typ)(in_(TPat))(nibs(((shape \ - Convex)(sort Typ))((shape(Concave 13))(sort \ - Typ))))))(shards(0 1))(children(((Secondary((id \ - 2283)(content(Whitespace\" \"))))(Tile((id \ - 2284)(label(D))(mold((out TPat)(in_())(nibs(((shape \ - Convex)(sort TPat))((shape Convex)(sort \ + ebeb7669-44b8-433a-9944-dc027f8f7003)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 37725f50-74ae-4651-a13a-489eddb08955)(content(Whitespace\" \ + \"))))(Tile((id \ + 20a12d27-d6b5-4514-ad6f-1e951c2d0391)(label(D))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2286)(content(Whitespace\" \")))))))))(Secondary((id \ - 2287)(content(Whitespace\" \"))))(Tile((id \ - 2288)(label(D))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2306)(content(Whitespace\" \"))))(Tile((id \ - 2304)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2316)(content(Whitespace\" \"))))(Tile((id \ - 2317)(label(D))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + c70dd6ff-391d-4c7c-a73d-62b8af7a5c10)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 084c5f67-3772-473b-8121-b5593490d98d)(content(Whitespace\" \ + \"))))(Tile((id \ + 374c499d-fbaf-4a2c-8e95-a8c4aab55992)(label(D))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 636bf99a-c682-4a09-9bc3-02abf03a2a95)(content(Whitespace\" \ + \"))))(Tile((id \ + 8f3851f6-33da-415b-82bc-8d7734089747)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + df4c4c83-a640-4b98-9992-cc466142b237)(content(Whitespace\" \ + \"))))(Tile((id \ + bc020cbc-2bee-4d21-aada-486e4657ca1a)(label(D))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2324)(content(Whitespace\" \"))))(Tile((id \ - 2321)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 80178c33-42d1-40a8-9f89-6cd7257cec81)(content(Whitespace\" \ + \"))))(Tile((id \ + c028b69c-8544-40ce-bd46-b370f61b6050)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2323)(content(Whitespace\" \"))))(Tile((id \ - 2327)(label(\"(\"\")\"))(mold((out \ + c7feb1ec-8ee4-4a45-852c-61dab26295d1)(content(Whitespace\" \ + \"))))(Tile((id \ + 69097f40-c4b8-40fc-8c3f-83320bb1c7f7)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2329)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2330)(content(Whitespace\" \"))))(Tile((id \ - 2331)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 14))(sort Typ))((shape(Concave 14))(sort \ + 9dfe9156-9cc5-4484-ad1b-6c2e1ba76e00)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 68821505-6886-4514-9cb7-ca680ef6f9fe)(content(Whitespace\" \ + \"))))(Tile((id \ + f0a182a8-44ea-4c80-b37e-26545127421e)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2333)(content(Whitespace\" \"))))(Tile((id \ - 2334)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + ee9e3c98-29c3-4191-96f7-d759ba9831d0)(content(Whitespace\" \ + \"))))(Tile((id \ + 03c0b912-b205-4ee3-83f4-20654cef76a4)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2341)(content(Whitespace\" \"))))(Tile((id \ - 2338)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 704883ad-e1f1-4931-8c20-75137f6125bb)(content(Whitespace\" \ + \"))))(Tile((id \ + e57b4dfc-0ec1-4c60-9114-4db7ed161100)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2345)(content(Whitespace\" \"))))(Tile((id \ - 2346)(label(\"(\"\")\"))(mold((out \ + 12d67f9f-300d-47d2-9456-b46834577095)(content(Whitespace\" \ + \"))))(Tile((id \ + 8f554256-0ab9-4c84-a1c2-63596877e225)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2347)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2348)(content(Whitespace\" \"))))(Tile((id \ - 2349)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 14))(sort Typ))((shape(Concave 14))(sort \ + b9860364-7fb8-4a87-9813-2bd5178200fd)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 6e303e7d-fe77-4b6d-80eb-674991ecebb2)(content(Whitespace\" \ + \"))))(Tile((id \ + f6db9b79-e371-44cd-acf3-18fd4f06770b)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2351)(content(Whitespace\" \"))))(Tile((id \ - 2352)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 8bdca6d8-d33a-4c35-9f51-021fc98c298e)(content(Whitespace\" \ + \"))))(Tile((id \ + 4fb9e567-2954-4690-b71e-8cc92ca17d13)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2353)(content(Whitespace\" \")))))((Secondary((id \ - 2355)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2377)(label(typfun ->))(mold((out \ - Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + 19eece83-ea6a-4e60-a5d6-4207048bc574)(content(Whitespace\" \ + \")))))((Secondary((id \ + 4b9fc364-d0a1-435e-a0d6-3a490349b143)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + b8c143a9-c3ee-41ad-81d4-53d28c0c861c)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2378)(content(Whitespace\" \ - \"))))(Tile((id 2380)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + 2029fa53-3073-4967-87a8-b0869112189f)(content(Whitespace\" \ + \"))))(Tile((id \ + 454ea17c-4c69-456f-bf12-55d3e1142ab1)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2381)(content(Whitespace\" \")))))))))(Secondary((id \ - 2384)(content(Whitespace\" \"))))(Tile((id 2391)(label(typfun \ + 23c91397-4f7f-4121-8e3b-bbdb2cf73612)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 60524143-0ca7-4857-8f40-cf6deea6407d)(content(Whitespace\" \ + \"))))(Tile((id \ + 24999367-7d4d-4a2f-888a-01caf8064af4)(label(typfun \ ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2392)(content(Whitespace\" \ - \"))))(Tile((id 2394)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + 697b85eb-ebaa-4da2-b3ff-f8784abce982)(content(Whitespace\" \ + \"))))(Tile((id \ + 9268bf3d-d2ad-45b8-a656-4c5fc7da9a8e)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2395)(content(Whitespace\" \")))))))))(Secondary((id \ - 2402)(content(Whitespace\" \"))))(Tile((id 2408)(label(fun \ + f7a80654-16be-46ef-84dc-cbbfe538eec1)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 4fac1b77-6181-4276-8df7-69ec0b498670)(content(Whitespace\" \ + \"))))(Tile((id \ + 14f05a85-9351-421d-8012-e644bee593b8)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2409)(content(Whitespace\" \ - \"))))(Tile((id 2411)(label(f))(mold((out \ + 1))(children(((Secondary((id \ + ec293b56-ef71-4d52-80e8-1dbf69fedf52)(content(Whitespace\" \ + \"))))(Tile((id \ + b3b4e67e-ec31-48d0-99c8-1fd0b776e3f3)(label(f))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2412)(content(Whitespace\" \")))))))))(Secondary((id \ - 2415)(content(Whitespace\" \"))))(Tile((id 2419)(label(fun \ + 8e65f50b-e702-4a38-b590-d3a8aa14e619)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + e2228bb4-f45a-4e38-aff2-f1a03def3d5e)(content(Whitespace\" \ + \"))))(Tile((id \ + 7359ea14-3040-402e-89dc-74daf4cb2482)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2420)(content(Whitespace\" \ - \"))))(Tile((id 2422)(label(\"(\"\")\"))(mold((out \ + 1))(children(((Secondary((id \ + 6023ad37-b805-415b-954e-30ac1380b014)(content(Whitespace\" \ + \"))))(Tile((id \ + 1528bbe3-9456-4d4e-92d7-43b29196f1a7)(label(\"(\"\")\"))(mold((out \ Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ - 2423)(label(x))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 2424)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 14))(sort Pat))((shape(Concave 14))(sort \ + c2919cb1-233a-4283-8b66-cf44fc4afef9)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 409eb345-2d10-4fa9-aa11-126678ce05bc)(label(,))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 14))(sort \ + Pat))((shape(Concave 14))(sort \ Pat))))))(shards(0))(children())))(Secondary((id \ - 2426)(content(Whitespace\" \"))))(Tile((id \ - 2427)(label(y))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ + 8a2cb8b6-9d5a-4754-8dda-8d8fe0e94e09)(content(Whitespace\" \ + \"))))(Tile((id \ + d0bd6124-c271-46ed-9371-5ff172659e12)(label(y))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ Pat))))))(shards(0))(children()))))))))(Secondary((id \ - 2428)(content(Whitespace\" \")))))))))(Secondary((id \ - 2431)(content(Whitespace\" \"))))(Tile((id \ - 2432)(label(\"(\"\")\"))(mold((out \ + 1ede3347-889a-421e-ab9f-9a76bb89b547)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 025702d6-85bb-4492-b77a-fcd80ce5b1d9)(content(Whitespace\" \ + \"))))(Tile((id \ + 44d77c85-e077-410e-850c-ccc2c10fc818)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2433)(label(f))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2452)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2453)(label(A))(mold((out \ - Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ - Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2440)(label(\"(\"\")\"))(mold((out \ - Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + 22214cfb-eb83-4531-b73e-7aed1cbee876)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 38c3df7e-a52e-488b-8153-cc0a0e400c81)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2442)(label(x))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Tile((id \ - 2443)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2445)(content(Whitespace\" \"))))(Tile((id \ - 2446)(label(f))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2455)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2456)(label(B))(mold((out \ + 82ad7a3a-04a9-451b-aa97-19bc0c7ecb39)(label(A))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2447)(label(\"(\"\")\"))(mold((out \ + d315a9cd-9383-456f-a0d1-9b96b08aed99)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2449)(label(y))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ - 2450)(content(Whitespace\" \")))))))))(Secondary((id \ - 2308)(content(Whitespace\" \"))))(Secondary((id \ - 2313)(content(Whitespace\" \"))))(Secondary((id \ - 2159)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4719)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4720)(content(Whitespace\" \"))))(Tile((id \ - 4725)(label(ex3))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 4727)(content(Whitespace\" \")))))((Secondary((id \ - 4728)(content(Whitespace\" \"))))(Tile((id \ - 4724)(label(apply_both))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2476)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2481)(label(Int))(mold((out \ + ffdcd079-0c86-4fb9-9a32-a6f10114522f)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ + c343faf6-4aec-4789-a364-1c38747c0ede)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 972f8813-9085-4dcf-8f65-91f4ccfff5f6)(content(Whitespace\" \ + \"))))(Tile((id \ + ad7b36cb-7b61-4988-af73-1751a7f90e5a)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 35f5379e-f09a-4416-8881-b3e555caa977)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 8c539c0f-b853-4aa4-98bf-874aa0d5487d)(label(B))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2483)(label(@< >))(mold((out \ + 0d94b84a-aba2-4fdd-bbeb-c6e96990f257)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 6346a4a7-211a-4b7b-af7a-8d3980f344b6)(label(y))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + 1374a8af-7da6-432f-8448-bf31d19fa4a1)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 4bad67e9-e3ec-4331-9db9-85eb4d51c10d)(content(Whitespace\" \ + \"))))(Secondary((id \ + 8ff64639-9a3a-4439-8dd4-a3e15280dd33)(content(Whitespace\" \ + \"))))(Secondary((id \ + 694712fd-f999-48ff-93c7-fc33b9b77094)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + fef28f13-33fe-449b-8cdb-6ebfd5762e15)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + ac4c6231-9f82-4ade-b8c9-d91728bf8ad4)(content(Whitespace\" \ + \"))))(Tile((id \ + 5de84be0-f611-4281-a794-7a0b0ff1118c)(label(ex3))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 3cb05235-9882-4486-b265-1cc2556c796f)(content(Whitespace\" \ + \")))))((Secondary((id \ + 5d92ec2c-1d17-4c65-bca3-9f32260e8b3e)(content(Whitespace\" \ + \"))))(Tile((id \ + cf076596-5f1d-4628-8197-5a5fec90a125)(label(apply_both))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + e1f8fd16-f236-4fc9-bc9a-b9289a4112f5)(label(@< >))(mold((out \ Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2490)(label(String))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2491)(label(\"(\"\")\"))(mold((out \ + 09beab66-f457-4dad-8f46-8e195d6e5e65)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + 98181850-6a50-4513-827b-4a9c90873912)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + cbf816ab-0f3a-47e0-8a6c-5d2394e0a427)(label(String))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + f703fbc5-53b3-49db-8748-d10d150098c0)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2494)(label(id))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Tile((id \ - 2495)(label(\"(\"\")\"))(mold((out \ + 797110e6-521d-4cbb-9941-19fccd65f36a)(label(id))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ + 51783bd8-663f-4e46-b00a-a0296c8cd7ac)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2501)(label(3))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2503)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2504)(content(Whitespace\" \"))))(Tile((id \ - 2517)(label(\"\\\"Hello World\\\"\"))(mold((out \ + 8fc7176c-fa6c-4cd7-9245-83b8702a4428)(label(3))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ - Convex)(sort \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 8116ef96-1cab-42f4-81de-213ecf812970)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 2f20f0f7-1675-4468-b2b6-cd7405f5aee4)(content(Whitespace\" \ + \"))))(Tile((id \ + 9f229a7b-bbad-4a9a-9e62-d9904862374c)(label(\"\\\"Hello \ + World\\\"\"))(mold((out Exp)(in_())(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 4732)(content(Whitespace\" \")))))))))(Secondary((id \ - 2526)(content(Whitespace\" \"))))(Secondary((id \ - 2548)(content(Comment\"# (3, \\\"Hello World\\\") \ - #\"))))(Secondary((id 2521)(content(Whitespace\" \ - \"))))(Secondary((id \ - 2457)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2549)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 2650)(content(Comment\"# Finally, here is a more in-depth, \ - yet applicable example: polymorphic map #\"))))(Secondary((id \ - 2550)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2932)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 2933)(content(Whitespace\" \"))))(Tile((id \ - 2943)(label(emptylist))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2944)(content(Whitespace\" \"))))(Tile((id \ - 2945)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + 1906060c-28fe-4257-8be4-2fd05219ef29)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 63719044-8f1c-4920-ba4f-e4b2170077c4)(content(Whitespace\" \ + \"))))(Secondary((id \ + 06d1fe4e-1834-48c0-ba2d-71886eefb57a)(content(Comment\"# (3, \ + \\\"Hello World\\\") #\"))))(Secondary((id \ + 9a45a5ec-c346-4ba0-b534-37ee71f5fdd1)(content(Whitespace\" \ + \"))))(Secondary((id \ + edef7a1c-2899-4e18-8228-c750ceff7ec8)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + b700ee2a-c5eb-4ee1-bbab-c4539ed9d797)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + df508fd5-afc8-4de6-8261-7425fd25105b)(content(Comment\"# \ + Finally, here is a more in-depth, yet applicable example: \ + polymorphic map #\"))))(Secondary((id \ + e354e9fe-f5ad-4c87-be05-96335dffbe31)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 202cef82-1c4d-4655-b6b6-41f9e9f7a73b)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 78570e13-c5ca-49d9-b93b-fd18ffc9a429)(content(Whitespace\" \ + \"))))(Tile((id \ + e91519e6-a65e-491f-b9a4-18b547b30d3a)(label(emptylist))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 7a1b5f10-90ae-48e0-b0f9-36ca4d2d3107)(content(Whitespace\" \ + \"))))(Tile((id \ + a72887db-4aaf-49cc-8e67-0f7541880f76)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2946)(content(Whitespace\" \"))))(Tile((id 2954)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + ebfa5ee4-9fd0-4f8d-bc75-47444311729d)(content(Whitespace\" \ + \"))))(Tile((id \ + 592e5425-2459-41ff-9228-07f766f8ccf7)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 2955)(content(Whitespace\" \ - \"))))(Tile((id 2956)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + 803a7b56-e0b3-4d80-ba8c-b65ff8517d93)(content(Whitespace\" \ + \"))))(Tile((id \ + 87240474-a39f-4923-85a5-2f102c7d0e32)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2958)(content(Whitespace\" \")))))))))(Secondary((id \ - 2959)(content(Whitespace\" \"))))(Tile((id 2960)(label([ \ + 6e4a8b34-2119-4f41-a61a-463ef0198a04)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + b1ab0026-aae9-4be9-b36d-eb3dd781adb1)(content(Whitespace\" \ + \"))))(Tile((id 8085a4f3-a54a-4666-9242-6184af5353c0)(label([ \ ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2961)(label(A))(mold((out \ + 1))(children(((Tile((id \ + 7559f86c-1c2c-4542-b97d-35f9fc803fe4)(label(A))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2963)(content(Whitespace\" \")))))((Secondary((id \ - 2964)(content(Whitespace\" \"))))(Tile((id 2972)(label(typfun \ + a7d1783a-03d9-4a83-a20c-224d0591481f)(content(Whitespace\" \ + \")))))((Secondary((id \ + 8a9f101c-6584-44e7-99a3-e372048b7445)(content(Whitespace\" \ + \"))))(Tile((id \ + 68c3ed3d-f500-4bd3-bcaf-ea9bdf9451ae)(label(typfun \ ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2973)(content(Whitespace\" \ - \"))))(Tile((id 2974)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + faa1695b-2e55-4667-8ec7-1558b3d85850)(content(Whitespace\" \ + \"))))(Tile((id \ + 38b03267-319e-4664-8372-efcdd79e85f4)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2976)(content(Whitespace\" \")))))))))(Secondary((id \ - 2978)(content(Whitespace\" \"))))(Tile((id \ - 2980)(label([]))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 2984)(content(Whitespace\" \")))))))))(Secondary((id \ - 2986)(content(Whitespace\" \"))))(Secondary((id \ - 3009)(content(Comment\"# polymorphic constant \ - #\"))))(Secondary((id \ - 2927)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2656)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 2657)(content(Whitespace\" \"))))(Tile((id \ - 2661)(label(map))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2662)(content(Whitespace\" \"))))(Tile((id \ - 2663)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + 228c224a-afad-44f4-a22a-eddf73b8d974)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 5ca59d99-25f7-486d-ac51-f549cb0a91b3)(content(Whitespace\" \ + \"))))(Tile((id \ + 0981b8f1-b372-41ba-bf9d-9e13d779a5a3)(label([]))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 9c58a1b5-6df1-4868-a078-9ee9a15baa7c)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + e188133e-4924-4f2e-be27-fcf311628729)(content(Whitespace\" \ + \"))))(Secondary((id \ + ee875eb7-54d4-4f95-886b-c49fe80ef2be)(content(Comment\"# \ + polymorphic constant #\"))))(Secondary((id \ + dd6f9538-a844-49fd-a02a-ac3a01e89512)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + eccaa669-c774-4a4d-bfdf-fc6f85153e3c)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + aa9c739b-6bf6-49fd-bd3b-40f2f9017ae4)(content(Whitespace\" \ + \"))))(Tile((id \ + 0f2b46f6-0a6f-4c5c-8682-3f59ad4b751f)(label(map))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 37696633-3cee-49a1-b614-1f87c67e2b70)(content(Whitespace\" \ + \"))))(Tile((id \ + 0dfd3441-ca14-4837-8b6e-152899e6d301)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2664)(content(Whitespace\" \"))))(Tile((id 2672)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + 4215c01a-0f39-4671-8210-aff41079081d)(content(Whitespace\" \ + \"))))(Tile((id \ + 88c46e29-1562-41bb-8c58-3a70ca2b7337)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 2673)(content(Whitespace\" \ - \"))))(Tile((id 2674)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + c0d24d93-992b-40a9-8d3a-b16aa88a939c)(content(Whitespace\" \ + \"))))(Tile((id \ + 15ea1b72-ecb0-451c-91e5-e55c0283ff01)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2676)(content(Whitespace\" \")))))))))(Secondary((id \ - 2677)(content(Whitespace\" \"))))(Tile((id 2685)(label(forall \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + ecfd54e9-8baa-4a1c-8f98-5f8657ba550d)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 6fe8a5a8-f3af-4a76-b03a-7843dca9f959)(content(Whitespace\" \ + \"))))(Tile((id \ + 155d7295-5673-4c5a-87b8-68d3053df95a)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 2686)(content(Whitespace\" \ - \"))))(Tile((id 2687)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + d64b0ee3-fcce-40bb-976d-149ce33e0b05)(content(Whitespace\" \ + \"))))(Tile((id \ + 722893eb-79bf-4a75-9491-d5e696d80fe9)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2689)(content(Whitespace\" \")))))))))(Secondary((id \ - 2690)(content(Whitespace\" \"))))(Tile((id \ - 2691)(label(\"(\"\")\"))(mold((out \ + 1fb2d0cc-1057-4c09-b0dc-eda66ca91edf)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + b491ae64-7e22-48fe-85f9-5c4c9fb6a864)(content(Whitespace\" \ + \"))))(Tile((id \ + 43465c96-ccf8-4251-aeb5-06f86e7a9ec0)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2692)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2701)(content(Whitespace\" \"))))(Tile((id \ - 2697)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 8918e371-6bc8-4291-b8fc-92f0ac4afa4a)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 6164fe07-2c6f-4daf-9c3e-5ec6468e0c02)(content(Whitespace\" \ + \"))))(Tile((id \ + 8bc001b1-7710-4877-b8fd-6fb9eba7c39d)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2698)(content(Whitespace\" \"))))(Tile((id \ - 2699)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 07510d7e-5ccc-46e7-9d96-456f01270a3e)(content(Whitespace\" \ + \"))))(Tile((id \ + a753c673-92ed-44c4-923b-8a95152174b2)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2702)(content(Whitespace\" \"))))(Tile((id \ - 2704)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 523f8d85-4fe6-494d-8699-a5438e0b960e)(content(Whitespace\" \ + \"))))(Tile((id \ + 66564dc5-1126-45b1-96b5-6e591777773b)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2705)(content(Whitespace\" \"))))(Tile((id \ - 2706)(label(\"(\"\")\"))(mold((out \ + a43abf64-f5d9-4b52-85ff-d962bc2408bf)(content(Whitespace\" \ + \"))))(Tile((id \ + a0be16ac-54d0-4529-b9e6-6347996157a3)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 28a5752a-c74f-432c-99b5-aa7539198b49)(label([ ]))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2707)(label([ ]))(mold((out Typ)(in_(Typ))(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2708)(label(A))(mold((out \ + f393e48d-68a3-446d-befb-87f27012a0e3)(label(A))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2719)(content(Whitespace\" \"))))(Tile((id \ - 2713)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 2e71f6dd-e285-47cf-b2a6-e1a4b9f45db3)(content(Whitespace\" \ + \"))))(Tile((id \ + e4f1cd33-3003-49be-98a4-ee4ad279b2b6)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2714)(content(Whitespace\" \"))))(Tile((id 2715)(label([ \ + 0950551e-141b-4a64-8297-21259177b3bb)(content(Whitespace\" \ + \"))))(Tile((id 3e01b2d4-90ac-441e-aa07-eee0abf36091)(label([ \ ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2716)(label(B))(mold((out \ + 1))(children(((Tile((id \ + c72fce8d-fade-423e-965c-fec2b626373f)(label(B))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ - 2720)(content(Whitespace\" \")))))((Secondary((id \ - 2721)(content(Whitespace\" \"))))(Secondary((id \ - 2722)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2730)(label(typfun ->))(mold((out \ - Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + e8f716f5-1b3f-4ee6-962e-4e078ce0bd37)(content(Whitespace\" \ + \")))))((Secondary((id \ + d067ebe8-0d92-451f-8093-5520bf5fb45d)(content(Whitespace\" \ + \"))))(Secondary((id \ + 419f3418-e474-41c3-ad4c-3b22a8dd9a61)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 0b4c829b-646e-4473-8d56-826d11fded2c)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2731)(content(Whitespace\" \ - \"))))(Tile((id 2732)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + faaa1f96-c99c-4430-a432-32be33368118)(content(Whitespace\" \ + \"))))(Tile((id \ + 3167378f-47ff-4023-8c32-62977c64c1bc)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2734)(content(Whitespace\" \")))))))))(Secondary((id \ - 2736)(content(Whitespace\" \"))))(Tile((id 2744)(label(typfun \ + 9b40799d-499e-4cf0-b5e1-c77c9db980e2)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 17cd6904-a1de-419b-bc8b-551ae07e88df)(content(Whitespace\" \ + \"))))(Tile((id \ + a74f4763-dd86-4124-840a-ac14797d15fa)(label(typfun \ ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2745)(content(Whitespace\" \ - \"))))(Tile((id 2746)(label(B))(mold((out \ + 1))(children(((Secondary((id \ + 30a14f5e-ca39-4f7d-bfb0-03e3f6281c58)(content(Whitespace\" \ + \"))))(Tile((id \ + 58c4bb9f-8a30-480e-a52b-38df655f9164)(label(B))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 2748)(content(Whitespace\" \")))))))))(Secondary((id \ - 2755)(content(Whitespace\" \"))))(Tile((id 2759)(label(fun \ + dfad2a33-2a2d-4df9-be18-2fe06e3548bb)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + f9b87bc9-1128-4dec-bf0c-014baff77334)(content(Whitespace\" \ + \"))))(Tile((id \ + 1fde687f-dfdb-4b5a-a8cc-9e81d9e6b522)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2760)(content(Whitespace\" \ - \"))))(Tile((id 2762)(label(f))(mold((out \ + 1))(children(((Secondary((id \ + dd314134-b69e-4426-b1a6-999a28f427fd)(content(Whitespace\" \ + \"))))(Tile((id \ + ae115273-4b54-46ce-a192-10047fe9e951)(label(f))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2763)(content(Whitespace\" \"))))(Tile((id \ - 2764)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + 11aa5133-b04f-4100-a2e3-9695c08e4e09)(content(Whitespace\" \ + \"))))(Tile((id \ + 1cb85726-ab00-4149-8246-c9440cde31c3)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2766)(content(Whitespace\" \"))))(Tile((id \ - 2775)(label(\"(\"\")\"))(mold((out \ + de0c889c-43ea-4f05-bf55-abf04c9d0d59)(content(Whitespace\" \ + \"))))(Tile((id \ + 4a5c3924-a66d-4067-8f6b-89ec8d7234ec)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 2776)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 2788)(content(Whitespace\" \"))))(Tile((id \ - 2780)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + f2a159b3-e8b9-40ff-9f79-5ca041c21a77)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 2c18b0d4-9eb0-430d-b72d-6d8c6e21be1e)(content(Whitespace\" \ + \"))))(Tile((id \ + 00a6aaf9-db5a-4aa1-9c65-b0d933a7553f)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2782)(content(Whitespace\" \"))))(Tile((id \ - 2783)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + ce1cc890-5fe0-4bbc-a55e-ec4d56cc7ef7)(content(Whitespace\" \ + \"))))(Tile((id \ + 2fa7a2b3-bb79-497b-b83f-e203a3d0abe3)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2784)(content(Whitespace\" \")))))))))(Secondary((id \ - 2787)(content(Whitespace\" \"))))(Tile((id 2792)(label(fun \ + ccad4dbb-bd06-4483-9828-276555d352de)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 336ec250-d844-403f-b23f-fa7753dc5068)(content(Whitespace\" \ + \"))))(Tile((id \ + 05929dbf-0f8d-4a96-83d1-3d993326c4e0)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2793)(content(Whitespace\" \ - \"))))(Tile((id 2795)(label(l))(mold((out \ + 1))(children(((Secondary((id \ + 8f63a82f-5f21-4948-8824-0346d46d1d46)(content(Whitespace\" \ + \"))))(Tile((id \ + 36ec28dd-5dfb-4745-9297-c026b99a54ed)(label(l))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2797)(content(Whitespace\" \"))))(Tile((id \ - 2798)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ + ebeb2e6e-f6f2-4e00-b98a-640b41f05e5c)(content(Whitespace\" \ + \"))))(Tile((id \ + f4ad62e1-8361-4bcd-aaf7-b68fea88eac6)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 2800)(content(Whitespace\" \"))))(Tile((id 2801)(label([ \ + 776f0b9d-1e87-45a8-b2a8-c51a6d7551f4)(content(Whitespace\" \ + \"))))(Tile((id 0f555e5d-4c58-49a6-a83f-a02000e3a9b9)(label([ \ ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 2802)(label(A))(mold((out \ + 1))(children(((Tile((id \ + 0506c0fd-a136-45a0-9b58-8818281c6192)(label(A))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2803)(content(Whitespace\" \")))))))))(Secondary((id \ - 2807)(content(Whitespace\" \"))))(Secondary((id \ - 4473)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2826)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2827)(content(Whitespace\" \ - \"))))(Tile((id 2829)(label(l))(mold((out \ + fe663aa2-62a0-481c-8076-902ec6e80465)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + ac80020e-0679-444c-908a-664fd265d287)(content(Whitespace\" \ + \"))))(Secondary((id \ + 0532ce74-b1fd-47cd-afd8-536a76b56eac)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 5cb54d04-1620-4898-b5ee-171a13a55cb2)(label(case \ + end))(mold((out Exp)(in_(Rul))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 826841f4-cbf3-4158-a661-b7915909567d)(content(Whitespace\" \ + \"))))(Tile((id \ + f2738d6c-44d1-4477-9320-98664a2abebf)(label(l))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 2838)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2839)(label(| =>))(mold((out \ + 0f7ec861-3dd7-48c7-bb98-1068d6018711)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 666f3305-9623-472a-a8e5-4a4821bdac0c)(label(| =>))(mold((out \ Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2841)(content(Whitespace\" \ - \"))))(Tile((id 2842)(label(h))(mold((out \ + 1))(children(((Secondary((id \ + d5a09c88-8fb8-4ea9-be8a-852be89e4f6c)(content(Whitespace\" \ + \"))))(Tile((id \ + 1417ddf8-e63c-463e-b541-e36920b01149)(label(h))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2843)(content(Whitespace\" \"))))(Tile((id \ - 2846)(label(::))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 6))(sort Pat))((shape(Concave 6))(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 2847)(content(Whitespace\" \"))))(Tile((id \ - 2848)(label(t))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ + d2e0fe19-dd90-445e-bd58-cf97d46d9b9a)(content(Whitespace\" \ + \"))))(Tile((id \ + ff3d12e2-c357-42a7-8f3e-a21c9fb9d451)(label(::))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 6))(sort \ + Pat))((shape(Concave 6))(sort \ Pat))))))(shards(0))(children())))(Secondary((id \ - 2849)(content(Whitespace\" \")))))))))(Secondary((id \ - 2852)(content(Whitespace\" \"))))(Tile((id \ - 2863)(label(f))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 2864)(label(\"(\"\")\"))(mold((out \ + 2a6b7167-756b-4d3d-9f07-98e53f430cca)(content(Whitespace\" \ + \"))))(Tile((id \ + ea24b8b4-1664-4b46-b9ad-c74d7bb8b2c4)(label(t))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + dbf53a0c-d1df-4fcf-b833-2ca674b3118a)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + e5b78a12-bf5c-41b7-a607-81db98a7709c)(content(Whitespace\" \ + \"))))(Tile((id \ + bcb2ac89-9866-44b7-ac86-bfa367efb43e)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 274061ca-2c5f-4cff-ab7f-e034d6165d6a)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2866)(label(h))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + e1822bcd-8a53-428d-9568-08ce796791ba)(label(h))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 2867)(content(Whitespace\" \"))))(Tile((id \ - 2870)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 6))(sort Exp))((shape(Concave 6))(sort \ + 8261c12e-167c-4b97-b895-076b16cb8956)(content(Whitespace\" \ + \"))))(Tile((id \ + 134da227-54ae-4138-bfd3-0ffd5bbb35bf)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - 2871)(content(Whitespace\" \"))))(Tile((id \ - 2874)(label(map))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 2878)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 2879)(label(A))(mold((out \ + cde794e2-1514-4ee5-8722-b4d27751fc43)(content(Whitespace\" \ + \"))))(Tile((id \ + 48901d44-b0e6-4948-90d0-99d20334c456)(label(map))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 5f38a51a-94ff-4f13-ba3b-312e507ab73a)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 7539694b-4e31-49a6-a32d-dbdf0a55ef35)(label(A))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2882)(label(@< >))(mold((out \ + 7f4d954d-2861-4c11-bec6-fb759b5a0ffe)(label(@< >))(mold((out \ Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2883)(label(B))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Tile((id \ - 2884)(label(\"(\"\")\"))(mold((out \ + d67b39fa-c196-4262-9888-426de588572e)(label(B))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + c51f52dc-b5ca-4bf4-a2ab-ed899b19cd24)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2886)(label(f))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children()))))))))(Tile((id \ - 2887)(label(\"(\"\")\"))(mold((out \ + af6d37cf-fc46-4007-90f3-60bce7e9157d)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ + 3c421466-068a-48d3-8367-5e9ecffdb962)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 2889)(label(t))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 33bdc742-e6a9-4f94-86c9-406c3aae5f29)(label(t))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 2890)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 2891)(label(| =>))(mold((out \ + aa7f11a8-0790-4b02-8466-3a3a9aa0c628)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 977253f6-0679-49a0-a5ae-bf8804d4d272)(label(| =>))(mold((out \ Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 2893)(content(Whitespace\" \ - \"))))(Tile((id 2925)(label(_))(mold((out \ + 1))(children(((Secondary((id \ + c4956a98-232b-45c1-8ba7-5730e460512e)(content(Whitespace\" \ + \"))))(Tile((id \ + 4460a1f9-8f3e-4c6e-8ef9-50d18ff587eb)(label(_))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 2926)(content(Whitespace\" \")))))))))(Secondary((id \ - 2899)(content(Whitespace\" \"))))(Tile((id \ - 3020)(label(emptylist))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 3023)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 3024)(label(B))(mold((out \ + 762cb02f-c9a4-4913-91f6-c3e63c1cdf08)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 44404719-7532-4ef8-a4e0-ef40b69eb8ac)(content(Whitespace\" \ + \"))))(Tile((id \ + bbe24e20-53c7-49a7-83e9-65f8ba722e51)(label(emptylist))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 321a3266-20dc-4471-a74f-a95a466e7e31)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 6c978a1d-d8a2-4ca6-8a8f-1d35c5fd21d5)(label(B))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 2836)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 2837)(content(Whitespace\" \")))))))))(Secondary((id \ - 2651)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4740)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4741)(content(Whitespace\" \"))))(Tile((id \ - 4746)(label(ex4))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 4748)(content(Whitespace\" \")))))((Secondary((id \ - 4749)(content(Whitespace\" \"))))(Tile((id \ - 4745)(label(map))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id 3033)(label(@< \ - >))(mold((out Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort \ - Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 3037)(label(Int))(mold((out \ + d9bbddf3-7123-496d-ac83-8e7ceef5b6de)(content(Whitespace\" \ + \"))))(Secondary((id \ + 01684518-f444-4731-852b-69ef9a5d9b43)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 3edb8b70-1ae0-496b-ad02-eb3693fc8f56)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 36c28bc5-a5cf-4acc-985c-2c955c7d820e)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 97de8089-37ac-4509-acc9-39012a0fdf3e)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 80d05981-1920-44d8-b42e-f18175935f70)(content(Whitespace\" \ + \"))))(Tile((id \ + 72ae731d-de2f-4ad8-a2d6-356bceae5577)(label(ex4))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 7028d808-2b29-4ca9-a4d3-1a5dacd93fa0)(content(Whitespace\" \ + \")))))((Secondary((id \ + 77fd1b46-bf93-4844-8f57-b111ba33d8d3)(content(Whitespace\" \ + \"))))(Tile((id \ + d18a0774-cfc4-4907-b460-b469053a3c0c)(label(map))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 504e60fc-928d-4308-96ca-fd31df0da48a)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 4f0f6316-3dd0-4479-bbd4-762b82b7c37e)(label(Int))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ - 3039)(label(@< >))(mold((out \ + 14993ad8-445e-45b3-b828-e4c0b43c834b)(label(@< >))(mold((out \ Exp)(in_(Typ))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3046)(label(String))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children()))))))))(Tile((id \ - 3051)(label(\"(\"\")\"))(mold((out \ + e91f5e5f-40db-4039-86de-833746dfac39)(label(String))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + ddbda949-29b7-4b34-8f11-05ed3fcd6f01)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3068)(label(string_of_int))(mold((out \ + 6d6bee77-2fa1-478e-997c-3540a5e97174)(label(string_of_int))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ - 3073)(label(\"(\"\")\"))(mold((out \ + 42c0e873-c3f1-4106-80a6-a2ed60f806f5)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3080)(label([ ]))(mold((out Exp)(in_(Exp))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Tile((id 3082)(label(1))(mold((out \ + 9cdabbd2-8198-4864-8f41-e855415362ea)(label([ ]))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 6484bcbc-b4cf-4c4c-b20f-7f554010051c)(label(1))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 3086)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3089)(label(2))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 85ce0fb1-0fd5-4ec6-bd55-a32bf8920ff2)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ Exp))))))(shards(0))(children())))(Tile((id \ - 3090)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ + fc87be7f-7ae8-495d-9beb-8a214a49f71c)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 2dc60eb3-a968-4efd-9f71-36058601c0c7)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ Exp))))))(shards(0))(children())))(Tile((id \ - 3092)(label(3))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 8c971b0e-ea6d-41df-b8c2-b5c3c2a4f908)(label(3))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ - 4753)(content(Whitespace\" \")))))))))(Secondary((id \ - 3101)(content(Whitespace\" \"))))(Secondary((id \ - 3125)(content(Comment\"# [\\\"1\\\", \\\"2\\\", \\\"3\\\"] \ + 935f2c82-7dc7-4899-b2aa-d473ad9e1cdc)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 7d0cb752-8863-4cf3-8b39-a859475c9eb5)(content(Whitespace\" \ + \"))))(Secondary((id \ + 1e8050d0-bbc2-467e-a83e-29856cace3c4)(content(Comment\"# \ + [\\\"1\\\", \\\"2\\\", \\\"3\\\"] #\"))))(Secondary((id \ + 8abda13b-ad37-4604-8f9a-d187bfd0c494)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + bf822fc1-bfad-46a5-970d-79a0d86ba99d)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 698e99c5-fbfc-467c-ac98-60fe4bb2ac9e)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 6de45367-5e16-4d4b-861c-e668d080fd94)(content(Comment\"# \ + Recursive types #\"))))(Secondary((id \ + 528d4204-ce5a-4d4d-8a65-499c165a93a6)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 22c11a80-9716-4d85-8478-84acbb2bb3e2)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 7c21acf4-f87c-4f87-96ed-9f3ce7854bee)(content(Comment\"# We \ + can express types that are the least fixed point of \ #\"))))(Secondary((id \ - 3126)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3128)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3129)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3147)(content(Comment\"# Recursive types \ - #\"))))(Secondary((id \ - 3148)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3149)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3266)(content(Comment\"# We can express types that are the \ - least fixed point of #\"))))(Secondary((id \ - 3267)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3319)(content(Comment\"# some type function with the rec \ - keyword. #\"))))(Secondary((id \ - 1472)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 681)(label(type = in))(mold((out Exp)(in_(TPat \ - Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 682)(content(Whitespace\" \"))))(Tile((id \ - 970)(label(MyList))(mold((out TPat)(in_())(nibs(((shape \ - Convex)(sort TPat))((shape Convex)(sort \ + eb66d375-5bc4-4510-9213-406754f1b3ab)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 5bd07da0-2cdc-4bed-b10e-8afdf2d40ed4)(content(Comment\"# some \ + type function with the rec keyword. #\"))))(Secondary((id \ + d563fa59-b243-4ee7-87ef-3393d1850a36)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 0a9260b0-6cb1-4f99-bfa5-07bc929cdbc2)(label(type = \ + in))(mold((out Exp)(in_(TPat Typ))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 7ad3ae39-3be4-4998-86a7-9c94d619ba34)(content(Whitespace\" \ + \"))))(Tile((id \ + 49357b25-92c9-4cd3-b04c-fea7d3c2ee30)(label(MyList))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 975)(content(Whitespace\" \")))))((Secondary((id \ - 3332)(content(Whitespace\" \"))))(Tile((id 891)(label(rec \ - .))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + b193ab38-767a-485a-9bda-27fe181a70fb)(content(Whitespace\" \ + \")))))((Secondary((id \ + cdadc496-6611-4ffc-b135-643b2b6e58fb)(content(Whitespace\" \ + \"))))(Tile((id \ + d8af8722-cf91-4f15-9c32-2eecdbb5d1dd)(label(rec \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ Typ))((shape(Concave 13))(sort Typ))))))(shards(0 \ - 1))(children(((Secondary((id 989)(content(Whitespace\" \ - \"))))(Tile((id 4015)(label(A))(mold((out \ + 1))(children(((Secondary((id \ + 16ba3fd3-2845-490b-a056-b8379608f7c8)(content(Whitespace\" \ + \"))))(Tile((id \ + 35911a26-36a2-4755-a0d5-40663bd5e3e3)(label(A))(mold((out \ TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ Convex)(sort \ - TPat))))))(shards(0))(children()))))))))(Secondary((id \ - 4013)(content(Whitespace\" \"))))(Tile((id \ - 1075)(label(\"(\"\")\"))(mold((out \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 32b2fb6f-0a3d-41bf-b4d7-90c0411c4a4f)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + a5c9177a-1a19-4bf5-968b-79dcd8a5f1ae)(content(Whitespace\" \ + \"))))(Tile((id \ + 21645f30-7293-4698-a5ef-c03a43418311)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 894)(label(Nil))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 851)(content(Whitespace\" \"))))(Tile((id \ - 849)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 10))(sort Typ))((shape(Concave 10))(sort \ + 2236339d-9e54-45ca-b4f0-a2adcf62fdd4)(label(Nil))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 2eda9a70-f5e3-4430-8ac3-94060fd5b62a)(content(Whitespace\" \ + \"))))(Tile((id \ + 724193cc-c749-44c9-86c9-24c6d5f02b21)(label(+))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 10))(sort \ + Typ))((shape(Concave 10))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 852)(content(Whitespace\" \"))))(Tile((id \ - 856)(label(Cons))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 868)(label(\"(\"\")\"))(mold((out \ + 494ef4ee-7336-4d8a-991b-843e8e09e6a4)(content(Whitespace\" \ + \"))))(Tile((id \ + 36cbd19c-bd46-418c-ac05-7ca72e3efc03)(label(Cons))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 4681bbb3-42ce-46c8-8a22-3259057a14a6)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 4021)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 873)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 14))(sort Typ))((shape(Concave 14))(sort \ + 8213139c-073b-46ca-a434-e32ffd0d2388)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + fffa4b09-8032-4007-a8e9-c1b4c9b3e4cf)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 875)(content(Whitespace\" \"))))(Tile((id \ - 4017)(label(A))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 61db4da2-294b-4285-96e3-718cb15577c8)(content(Whitespace\" \ + \"))))(Tile((id \ + 9692e5ad-a529-43ef-a693-413e0ab21a31)(label(A))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ - 885)(content(Whitespace\" \")))))))))(Secondary((id \ - 3562)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4217)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4356)(content(Comment\"# Hazel does not (yet) support \ - higher-kinded or existential types, #\"))))(Secondary((id \ - 4287)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4357)(content(Comment\"# So we cannot implement our own \ - polymorphic lists. #\"))))(Secondary((id \ - 4218)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3782)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3899)(content(Comment\"# Now anything that returns an element \ - of the least fixed point matches MyList. \ + 990cc418-00f2-4c98-9395-ad95bca66884)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 3701484f-c796-4d38-bce7-4f25b4c3637d)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 193cfb02-bcdb-47e2-80c5-4775c7f11a82)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 8c0f2c04-fc2c-4fdf-8f0c-83644d1be509)(content(Comment\"# \ + Hazel does not (yet) support higher-kinded or existential \ + types, #\"))))(Secondary((id \ + 4810f7f2-213a-465d-9b61-81cf18482fa8)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 0eaf40c5-5a8b-4cbb-aa19-18ba099847eb)(content(Comment\"# So \ + we cannot implement our own polymorphic lists. \ #\"))))(Secondary((id \ - 3900)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 3905)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 3906)(content(Whitespace\" \"))))(Tile((id \ - 3907)(label(x))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 3909)(content(Whitespace\" \"))))(Tile((id \ - 3910)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 3911)(content(Whitespace\" \"))))(Tile((id \ - 3918)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 579ceeeb-258a-4089-a115-5627e2eaea58)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 7bfbd599-e516-45a7-a725-cb39be5c8729)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 887616c9-6707-4e70-ab3d-62996ce73e70)(content(Comment\"# Now \ + anything that returns an element of the least fixed point \ + matches MyList. #\"))))(Secondary((id \ + 6f06209e-4913-4da3-ae91-5bd283668594)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 33ed3a5b-0867-43d7-8cc2-2c8ca4c758e7)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 0370f42e-bd6c-490a-bb7d-920d2f8a8aae)(content(Whitespace\" \ + \"))))(Tile((id \ + 5bae080b-2019-4ffd-a2a9-2a972fcda28d)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 4079c066-6ef0-4310-83c6-56fe7fd7670e)(content(Whitespace\" \ + \"))))(Tile((id \ + a0c477e1-9ef3-4b38-a67c-d5d22e96471d)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 3979)(content(Whitespace\" \")))))((Secondary((id \ - 3920)(content(Whitespace\" \"))))(Tile((id \ - 3995)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3926)(label(\"(\"\")\"))(mold((out \ + 93cd7df1-2b4d-4582-acf7-2cb0d46f6313)(content(Whitespace\" \ + \"))))(Tile((id \ + e62970f7-e979-49fb-bde6-c008d8d79a70)(label(MyList))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 1b69d275-5bd5-489b-a340-7aafdfd14d12)(content(Whitespace\" \ + \")))))((Secondary((id \ + 5c867417-e06d-4873-b84d-041e25dcb2d0)(content(Whitespace\" \ + \"))))(Tile((id \ + 2cf5af86-df22-4aba-a044-17d75a3ae989)(label(Cons))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 7e122a6b-5f64-4a7e-90ae-0878e0d82f03)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3927)(label(1))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3929)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ + 1d783d64-398f-4ad6-9eae-b3490775e34c)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + df60de96-d925-4ca9-beca-a392fa9d3a33)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - 3930)(content(Whitespace\" \"))))(Tile((id \ - 3935)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3936)(label(\"(\"\")\"))(mold((out \ + a798be71-5b99-4f2e-a8e2-e923f9609370)(content(Whitespace\" \ + \"))))(Tile((id \ + 8565ea1f-2353-458d-9439-7f379d71cebd)(label(Cons))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 7ece0aa1-030f-42ec-98ef-b2628aac965c)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3937)(label(2))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3939)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ + e755b115-0361-453e-b274-9f9cb8a0c262)(label(2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 4459b0c1-70f4-4101-a896-21725d8c2a4e)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - 3940)(content(Whitespace\" \"))))(Tile((id \ - 3945)(label(Cons))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3946)(label(\"(\"\")\"))(mold((out \ + 9bc6d0d7-59d4-4cff-819a-6fa718e28414)(content(Whitespace\" \ + \"))))(Tile((id \ + 9bcc25fd-a616-49f1-9f53-f12a36e09354)(label(Cons))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + e5ad642e-1071-4a7b-ae6f-d6c8b4b34403)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 3947)(label(3))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Tile((id \ - 3949)(label(,))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 14))(sort Exp))((shape(Concave 14))(sort \ + fcd291b3-e052-402b-be90-a4a138f94cce)(label(3))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + bab8fe07-56b3-4a03-8a70-cad1d19c41ce)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - 3950)(content(Whitespace\" \"))))(Tile((id \ - 3954)(label(Nil))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 952bc037-e9e7-42a4-9dd8-24f64cbaedd9)(content(Whitespace\" \ + \"))))(Tile((id \ + 63e70629-8a00-4987-adcc-d9b7edb62ecc)(label(Nil))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))))))))))))(Secondary((id \ - 3957)(content(Whitespace\" \")))))))))(Secondary((id \ - 3783)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3563)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4216)(content(Comment\"# Note that if the sum is the top \ - level operator, #\"))))(Secondary((id \ - 3616)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3701)(content(Comment\"# type aliases are implicitly least \ - fixed points on their own name: #\"))))(Secondary((id \ - 990)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 1002)(label(type = in))(mold((out Exp)(in_(TPat \ - Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 1011)(content(Whitespace\" \"))))(Tile((id \ - 1091)(label(MyList2))(mold((out TPat)(in_())(nibs(((shape \ - Convex)(sort TPat))((shape Convex)(sort \ + 3c1a3bf1-ed31-4739-885e-ad254fc292f2)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + b75b8ab1-8759-45b5-ad5b-ed90197258da)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 935b835c-261d-47fc-bee8-068e25da32a8)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + fb36a038-d3c2-48ec-9310-1ccb658b327a)(content(Comment\"# Note \ + that if the sum is the top level operator, \ + #\"))))(Secondary((id \ + 3c729241-60ac-46a3-86db-92a070ffa4d5)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + f7670b91-4175-4a41-b92a-232fd61e8eec)(content(Comment\"# type \ + aliases are implicitly least fixed points on their own name: \ + #\"))))(Secondary((id \ + ff8533bf-ba1e-4237-8c1c-e3130b234e64)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + e940b831-775d-4d20-8c4e-cf380df7c704)(label(type = \ + in))(mold((out Exp)(in_(TPat Typ))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + fa4039e4-3ac6-4d02-9df8-449e895958cd)(content(Whitespace\" \ + \"))))(Tile((id \ + 05f24c94-0119-4bd5-b234-a1dbdaeab975)(label(MyList2))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 1141)(content(Whitespace\" \")))))((Secondary((id \ - 3513)(content(Whitespace\" \"))))(Tile((id \ - 3507)(label(Nil))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 3378)(content(Whitespace\" \"))))(Tile((id \ - 3379)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 10))(sort Typ))((shape(Concave 10))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 3381)(content(Whitespace\" \"))))(Tile((id \ - 3385)(label(Cons))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 3386)(label(\"(\"\")\"))(mold((out \ + a5939fcf-4a82-49d3-a9dc-8d899ad579f6)(content(Whitespace\" \ + \")))))((Secondary((id \ + 4e843e4a-0c21-4bd3-9163-bad05c819bc8)(content(Whitespace\" \ + \"))))(Tile((id \ + 8f4764bd-552d-47b3-a75f-8177eacbfad3)(label(Nil))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 2b1728e8-6ba7-4cbb-9064-aec652c83d87)(content(Whitespace\" \ + \"))))(Tile((id \ + 6585a36d-b5e9-4a63-8d45-bca7e5c38cf0)(label(+))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 10))(sort \ + Typ))((shape(Concave 10))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 77c58ade-ef24-46bd-8fad-1fe0dacbc953)(content(Whitespace\" \ + \"))))(Tile((id \ + a97829e0-ec9c-4941-affb-26a072f73fc5)(label(Cons))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 12e14808-3cec-40de-88dc-d9d030c3e0a8)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 3705)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 3389)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 14))(sort Typ))((shape(Concave 14))(sort \ + b501c4ea-e896-49a6-a03e-e15a8d8e9a51)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + e853b31d-1d90-47b0-a37c-9fbec3a18544)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 3391)(content(Whitespace\" \"))))(Tile((id \ - 3398)(label(MyList2))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 6fa80101-ad62-45fb-b1a3-ebb1a1cfb16d)(content(Whitespace\" \ + \"))))(Tile((id \ + 22588755-b59d-4f05-9905-b901a1db3f30)(label(MyList2))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 3399)(content(Whitespace\" \")))))))))(Secondary((id \ - 3706)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 3715)(label(type = in))(mold((out Exp)(in_(TPat \ - Typ))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 3716)(content(Whitespace\" \"))))(Tile((id \ - 4079)(label(Broken))(mold((out TPat)(in_())(nibs(((shape \ - Convex)(sort TPat))((shape Convex)(sort \ + c8115f34-99e0-441c-9313-b15a577eb3eb)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 56e8a3e4-e828-44df-a3c8-e7b1f883e6fc)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + ecf2538d-f121-418b-b6ec-ffb5c0a67f70)(label(type = \ + in))(mold((out Exp)(in_(TPat Typ))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + de814c18-7e95-4f76-9ee7-d20266a3d78e)(content(Whitespace\" \ + \"))))(Tile((id \ + cd5bc989-4ae9-48fa-82fb-a5ab4e320674)(label(Broken))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ TPat))))))(shards(0))(children())))(Secondary((id \ - 3730)(content(Whitespace\" \")))))((Secondary((id \ - 3740)(content(Whitespace\" \"))))(Tile((id \ - 4111)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 4122)(content(Whitespace\" \"))))(Tile((id \ - 4121)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 8a26bf51-7c01-4f19-b61d-3f6cf0d623e7)(content(Whitespace\" \ + \")))))((Secondary((id \ + c8f6eebf-2e02-444f-b76a-e447af05ce9b)(content(Whitespace\" \ + \"))))(Tile((id \ + 0d01d510-b89e-44f8-b5fa-51b2ae3019d9)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + b7bf4f3b-2c80-48b8-9216-3ced31d7e2e7)(content(Whitespace\" \ + \"))))(Tile((id \ + 8e13455f-e289-48c1-9c66-c1d26e2092c7)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 3744)(content(Whitespace\" \"))))(Tile((id \ - 4120)(label(\"(\"\")\"))(mold((out \ + c0577a87-5d87-4f80-861a-c1ef1406b627)(content(Whitespace\" \ + \"))))(Tile((id \ + af30d9ee-ba31-4634-aee7-8671323584d8)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 4134)(label(HasInt))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 4135)(label(\"(\"\")\"))(mold((out \ + 8026c0f4-2334-4d9e-beec-c84c887da32c)(label(HasInt))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + e6c62de9-7dbe-4551-b683-eafeb333cbf1)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 4138)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 7cfa00aa-8ac0-428c-a4d8-3e1522f514d3)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children()))))))))(Secondary((id \ - 4062)(content(Whitespace\" \"))))(Tile((id \ - 4063)(label(+))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 10))(sort Typ))((shape(Concave 10))(sort \ + 1843b6d8-6591-45a8-b6d1-735229c0966a)(content(Whitespace\" \ + \"))))(Tile((id \ + ac02cd59-e2b2-4ddb-b3ed-34f055d805c6)(label(+))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 10))(sort \ + Typ))((shape(Concave 10))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 4065)(content(Whitespace\" \"))))(Tile((id \ - 4149)(label(HasMore))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 4098)(label(\"(\"\")\"))(mold((out \ + cac41e52-5cc4-46f3-bb90-a3abaaeee9ca)(content(Whitespace\" \ + \"))))(Tile((id \ + 389c16e0-7203-4142-9eca-b4246ce61c4c)(label(HasMore))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 6624e15f-6510-40e3-b646-de90440393f8)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape(Concave 1))(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 4154)(label(Int))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Tile((id \ - 4155)(label(,))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 14))(sort Typ))((shape(Concave 14))(sort \ + e1076ac2-2a95-4a69-a62c-261ab97d6dde)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 1ba0a1ea-2382-4a3c-95d2-bca9f7ba6d79)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 14))(sort \ + Typ))((shape(Concave 14))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 4156)(content(Whitespace\" \"))))(Tile((id \ - 4153)(label(Broken))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + 57b01c61-7ac0-4dfc-9ed4-6f5a6d38e57d)(content(Whitespace\" \ + \"))))(Tile((id \ + 45ddb6b3-449e-49f9-9ac7-0a65fe083166)(label(Broken))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ - 4106)(content(Whitespace\" \")))))))))(Secondary((id \ - 3779)(content(Whitespace\" \"))))(Secondary((id \ - 3780)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 3781)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 907)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4566)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4567)(content(Whitespace\" \"))))(Tile((id \ - 4585)(label(list_of_mylist))(mold((out \ - Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ - Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 921)(content(Whitespace\" \"))))(Tile((id \ - 4410)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 4412)(content(Whitespace\" \"))))(Tile((id \ - 4435)(label(\"(\"\")\"))(mold((out \ + 7849f81d-3ffc-45fb-8c6f-deca793f4340)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + e520d9d4-efc0-4050-9d28-9408015601f0)(content(Whitespace\" \ + \"))))(Secondary((id \ + 9d15c792-44f0-4b64-96b4-c01553f092ac)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + b5ac9def-818d-4cc9-a69e-b6c48bb3cf4a)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 16e84b97-6c21-457e-a9db-be37201ee08c)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + dcec6c2e-de60-4b66-a700-5ebe7a65b3cc)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 805fb44d-81bc-4f8e-b6d6-7fecccd366d6)(content(Whitespace\" \ + \"))))(Tile((id \ + 1b33ea74-291d-4177-a4cc-32150cc262c6)(label(list_of_mylist))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + fa5b0bfb-d0db-47f1-9248-36b4ca53105a)(content(Whitespace\" \ + \"))))(Tile((id \ + 0329d949-b67e-4f75-84c5-dac81ce19f53)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 6fafb86c-61e0-4497-9b66-088252c58d00)(content(Whitespace\" \ + \"))))(Tile((id \ + eaf6d9b9-9e6f-4399-b3e5-208475e22a8a)(label(\"(\"\")\"))(mold((out \ Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ - 4418)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 4448)(content(Whitespace\" \"))))(Tile((id \ - 4439)(label(->))(mold((out Typ)(in_())(nibs(((shape(Concave \ - 6))(sort Typ))((shape(Concave 6))(sort \ + 0cc9f249-f565-4923-936a-423a5c420bba)(label(MyList))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 909fa81c-98c3-4b79-8995-efb831fb05a8)(content(Whitespace\" \ + \"))))(Tile((id \ + 9e28a68b-7554-4af2-a9be-942c1110024e)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 4441)(content(Whitespace\" \"))))(Tile((id 4603)(label([ \ + fb0b7814-07ee-4953-95d4-f30c5d1a28df)(content(Whitespace\" \ + \"))))(Tile((id 1d502020-0204-4ae8-8192-d1967f0631c0)(label([ \ ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ Typ))((shape Convex)(sort Typ))))))(shards(0 \ - 1))(children(((Tile((id 4444)(label(Int))(mold((out \ + 1))(children(((Tile((id \ + 11378050-b326-435e-8af8-6f42f2e49778)(label(Int))(mold((out \ Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ Convex)(sort \ Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ - 4604)(content(Whitespace\" \")))))((Secondary((id \ - 4449)(content(Whitespace\" \"))))(Tile((id 4453)(label(fun \ + 1bf827f8-b572-4b9c-b34a-e1f5b0f0da30)(content(Whitespace\" \ + \")))))((Secondary((id \ + 66da49bf-a4d2-4e29-b778-b452a83e05e9)(content(Whitespace\" \ + \"))))(Tile((id \ + dce1d474-d747-4379-8ac6-f763c0983a91)(label(fun \ ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ Exp))((shape(Concave 13))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 4454)(content(Whitespace\" \ - \"))))(Tile((id 4458)(label(myl))(mold((out \ + 1))(children(((Secondary((id \ + 197cb6d3-e061-47d2-a835-ddb8f7a2d20e)(content(Whitespace\" \ + \"))))(Tile((id \ + acca15d8-ce9c-4705-9b01-752506a181a1)(label(myl))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 4459)(content(Whitespace\" \"))))(Tile((id \ - 4460)(label(:))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 11))(sort Pat))((shape(Concave 11))(sort \ - Typ))))))(shards(0))(children())))(Secondary((id \ - 4462)(content(Whitespace\" \"))))(Tile((id \ - 4468)(label(MyList))(mold((out Typ)(in_())(nibs(((shape \ - Convex)(sort Typ))((shape Convex)(sort \ + c284858d-33ee-41e8-bb6b-e7a3785347d5)(content(Whitespace\" \ + \"))))(Tile((id \ + b6b34912-9e5d-46db-8e71-da92a30d8530)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 11))(sort \ + Pat))((shape(Concave 11))(sort \ Typ))))))(shards(0))(children())))(Secondary((id \ - 4469)(content(Whitespace\" \")))))))))(Secondary((id \ - 4472)(content(Whitespace\" \"))))(Secondary((id \ - 4479)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4484)(label(case end))(mold((out Exp)(in_(Rul))(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 4485)(content(Whitespace\" \ - \"))))(Tile((id 4489)(label(myl))(mold((out \ + b6c140b8-77c7-4678-8600-86bf855f47dc)(content(Whitespace\" \ + \"))))(Tile((id \ + 335ac528-48d9-4e90-8d14-daf02bc2e744)(label(MyList))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 9b635b29-dd86-41a5-afe5-98e20f056263)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 3da32ede-874a-49f7-992d-94a620f990e3)(content(Whitespace\" \ + \"))))(Secondary((id \ + 3ceacb87-72e8-4cef-8154-190452625783)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 56e4366c-41dc-4518-bfad-e088baae8ae1)(label(case \ + end))(mold((out Exp)(in_(Rul))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + a35555f6-5351-4d16-a0bd-d1e18d7801ce)(content(Whitespace\" \ + \"))))(Tile((id \ + b17c5c27-7cbe-454e-b611-0d90f795189b)(label(myl))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ - 4490)(content(Whitespace\" \"))))(Secondary((id \ - 4491)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4492)(label(| =>))(mold((out \ + afdb8805-7c66-4af2-873e-24813d6529ce)(content(Whitespace\" \ + \"))))(Secondary((id \ + 28d13098-67c5-4ed6-9526-099cd842b85c)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 07d15b6d-f0f4-4670-820a-0fbd56a208c7)(label(| =>))(mold((out \ Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 4494)(content(Whitespace\" \ - \"))))(Tile((id 4497)(label(Nil))(mold((out \ + 1))(children(((Secondary((id \ + 94141f1d-753d-4ab9-a519-f781bdda56dd)(content(Whitespace\" \ + \"))))(Tile((id \ + e4a58087-c41a-4a12-a8da-c45bd917c0a1)(label(Nil))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ - 4498)(content(Whitespace\" \")))))))))(Secondary((id \ - 4506)(content(Whitespace\" \"))))(Tile((id \ - 4508)(label([]))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4509)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4510)(label(| =>))(mold((out \ + 00902ec1-0666-4bb6-858b-db5295b6271e)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 4ab05820-b00e-422a-a998-5f14b49a46a9)(content(Whitespace\" \ + \"))))(Tile((id \ + b88b20fc-86fb-48e2-badf-06f6c0ad4a87)(label([]))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + b55be10d-dbce-43f5-a69b-64450d2f0eae)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + ca06d3d8-49e0-45ae-9fa3-c369c7d63deb)(label(| =>))(mold((out \ Rul)(in_(Pat))(nibs(((shape(Concave 19))(sort \ Exp))((shape(Concave 19))(sort Exp))))))(shards(0 \ - 1))(children(((Secondary((id 4512)(content(Whitespace\" \ - \"))))(Tile((id 4516)(label(Cons))(mold((out \ + 1))(children(((Secondary((id \ + ebc90337-9c9a-48f3-982e-78dd373c2af4)(content(Whitespace\" \ + \"))))(Tile((id \ + c94a1c23-2922-4b09-8c90-ab1859a2f652)(label(Cons))(mold((out \ Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ - 4517)(label(\"(\"\")\"))(mold((out \ + 280a5024-fe68-4508-919b-bc6072aa320c)(label(\"(\"\")\"))(mold((out \ Pat)(in_(Pat))(nibs(((shape(Concave 1))(sort Pat))((shape \ Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ - 4519)(label(h))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Tile((id \ - 4520)(label(,))(mold((out Pat)(in_())(nibs(((shape(Concave \ - 14))(sort Pat))((shape(Concave 14))(sort \ + e1241ab0-e63e-46c0-bcb1-d5cf501c7d68)(label(h))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 7076e557-cff2-4587-99d8-7323b637eaa5)(label(,))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 14))(sort \ + Pat))((shape(Concave 14))(sort \ Pat))))))(shards(0))(children())))(Secondary((id \ - 4522)(content(Whitespace\" \"))))(Tile((id \ - 4525)(label(t))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ + b15f353d-22a1-4f82-962b-21eeb1709a3b)(content(Whitespace\" \ + \"))))(Tile((id \ + 29908b41-4852-4fed-a2be-a8201b46b324)(label(t))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ Pat))))))(shards(0))(children()))))))))(Secondary((id \ - 4526)(content(Whitespace\" \")))))))))(Secondary((id \ - 4529)(content(Whitespace\" \"))))(Tile((id \ - 4530)(label(h))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ - Exp))))))(shards(0))(children())))(Secondary((id \ - 4531)(content(Whitespace\" \"))))(Tile((id \ - 4534)(label(::))(mold((out Exp)(in_())(nibs(((shape(Concave \ - 6))(sort Exp))((shape(Concave 6))(sort \ + 282a4121-76db-46b2-92f2-c0b3bea39dab)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + d2bace67-f8aa-4fb7-b767-ff056b2db439)(content(Whitespace\" \ + \"))))(Tile((id \ + 52d40c83-e37a-4e99-a9f9-cce2a9bee532)(label(h))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 726272aa-84f1-4832-bce7-abf746dd38ac)(content(Whitespace\" \ + \"))))(Tile((id \ + cdc66ee5-157b-46bd-bd7b-1f5adf1eaf00)(label(::))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - 4535)(content(Whitespace\" \"))))(Tile((id \ - 4549)(label(list_of_mylist))(mold((out \ + 6a2d26fd-953a-4bd7-96af-01a5e67c5164)(content(Whitespace\" \ + \"))))(Tile((id \ + 3d383ccc-98af-43c0-811c-71cf543f3560)(label(list_of_mylist))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 4550)(label(\"(\"\")\"))(mold((out \ + 34f0131a-6046-42b7-acc3-0e9b115598e9)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 4552)(label(t))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 7644fb73-3d7b-4647-89a1-17ac8db02acf)(label(t))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 4560)(content(Whitespace\" \"))))(Secondary((id \ - 4554)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - 4601)(content(Whitespace\" \")))))))))(Secondary((id \ - 4606)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ - 4759)(label(let = in))(mold((out Exp)(in_(Pat \ - Exp))(nibs(((shape Convex)(sort Exp))((shape(Concave \ - 16))(sort Exp))))))(shards(0 1 2))(children(((Secondary((id \ - 4760)(content(Whitespace\" \"))))(Tile((id \ - 4765)(label(ex5))(mold((out Pat)(in_())(nibs(((shape \ - Convex)(sort Pat))((shape Convex)(sort \ - Pat))))))(shards(0))(children())))(Secondary((id \ - 4767)(content(Whitespace\" \")))))((Secondary((id \ - 4768)(content(Whitespace\" \"))))(Tile((id \ - 4764)(label(list_of_mylist))(mold((out \ + 4c34a3ca-0ad2-4452-8353-edc564632dd3)(content(Whitespace\" \ + \"))))(Secondary((id \ + b46b62aa-f261-440b-a185-d0d676172b7e)(content(Whitespace\" \ + \"))))(Secondary((id \ + a48cde36-a585-4160-9422-90e3f070e845)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + cd5ed745-ec98-409e-ac1f-234b381dce78)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 6dece3b9-a529-490e-91f2-12e76091b87f)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 287d9620-78ca-4128-9b32-8f9cb6b58760)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 16))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 80255e8c-d69c-49e8-a4da-becb2c97c9a6)(content(Whitespace\" \ + \"))))(Tile((id \ + 5e33ed39-557f-4503-a948-ffc0a793cd4d)(label(ex5))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 9fbd2e14-8f09-4035-8020-e8f44fba8526)(content(Whitespace\" \ + \")))))((Secondary((id \ + f767e5a7-54ab-44d3-a224-fffdadf9da4a)(content(Whitespace\" \ + \"))))(Tile((id \ + ad84dbab-bb06-43c8-8920-1b9e5e8c9cd8)(label(list_of_mylist))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ - 4621)(label(\"(\"\")\"))(mold((out \ + cefbaa1c-b1dc-4728-a64d-1663b18eec41)(label(\"(\"\")\"))(mold((out \ Exp)(in_(Exp))(nibs(((shape(Concave 1))(sort Exp))((shape \ Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ - 4623)(label(x))(mold((out Exp)(in_())(nibs(((shape \ - Convex)(sort Exp))((shape Convex)(sort \ + 8dd0ee06-28a5-424b-93b3-2c269447b2fa)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ Exp))))))(shards(0))(children()))))))))(Secondary((id \ - 4771)(content(Whitespace\" \")))))))))(Secondary((id \ - 4773)(content(Whitespace\" \"))))(Secondary((id \ - 4640)(content(Comment\"# [1, 2, 3] #\"))))(Secondary((id \ - 4643)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4644)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4645)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ - 4673)(content(Comment\"# All output from examples: \ - #\"))))(Secondary((id \ - 4674)(content(Whitespace\"\\226\\143\\142\")))))()))))))(caret \ + c24e59ed-e80f-4816-afcc-d222b126c80a)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 140a3fe3-246f-4a21-bf2d-aac3c7ea1eab)(content(Whitespace\" \ + \"))))(Secondary((id \ + d006bb40-713e-4973-9d8b-34ff0316612c)(content(Comment\"# [1, \ + 2, 3] #\"))))(Secondary((id \ + 2fff78bc-2182-4db7-bfa8-33fe02a69a5b)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 1096a58b-888f-47e9-9318-313d0f728a9c)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 26bec031-02af-4b4d-967f-a3b8fa91866b)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + ec44021a-5905-4176-8a43-e4b18ecee191)(content(Comment\"# All \ + output from examples: #\"))))(Secondary((id \ + a54fbe78-5b70-4bff-a1b0-f75d699e2d17)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 7f3190eb-b200-4e27-b89e-64483682f7cb)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 8a74a004-7d34-4e27-8fa7-bc1464a894d7)(label(ex1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 4ecc4b06-6a0d-449d-a7a9-507babe76cf8)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + a14aabb1-2f9e-405f-a6b1-49e947e6f8f0)(content(Whitespace\" \ + \"))))(Tile((id \ + bb8c31bc-af07-43ea-aa54-cebe3b7fe4c7)(label(ex2))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + e365c1ab-868b-419e-96e8-c11185577df8)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + adc45428-7b5c-4e79-9f5d-a70170063fc5)(content(Whitespace\" \ + \"))))(Tile((id \ + f25fdd38-87ca-44b2-bd55-3b1c13e31c51)(label(ex3))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 848d336b-5c6a-4c2f-848d-474fdb03b8d7)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 6dfa74ec-c592-42a4-a583-96e241120cef)(content(Whitespace\" \ + \"))))(Tile((id \ + 521e9214-e5ca-4c1d-995c-1d0b12a4aa20)(label(ex4))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 4a995d1a-3021-45dd-a4d7-13cff4af4385)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 14))(sort \ + Exp))((shape(Concave 14))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + f335f93b-9ff4-47f8-8043-301b1f88d1f7)(content(Whitespace\" \ + \"))))(Tile((id \ + 6d11e3ff-91bd-4a63-8233-0f2ff4c37428)(label(ex5))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))))))))()))(ancestors())))(caret \ Outer))"; backup_text = "# Polymorphism #\n\n\ @@ -15102,7 +15502,7 @@ let startup : PersistentData.t = typfun A -> typfun B -> fun f : (A -> B) -> fun l : [A] -> \n\ case l\n\ | h :: t => f(h) :: map@@(f)(t)\n\ - | _ => emptylist@\n\ + | _ => emptylist@ \n\ end in\n\ let ex4 = map@@(string_of_int)([1,2,3]) in # \ [\"1\", \"2\", \"3\"] #\n\n\n\ @@ -15125,7 +15525,7 @@ let startup : PersistentData.t = let list_of_mylist : (MyList -> [Int]) = fun myl : MyList -> \n\ case myl \n\ | Nil => []\n\ - | Cons(h, t) => h :: list_of_mylist(t) \n\ + | Cons(h, t) => h :: list_of_mylist(t) \n\ end in\n\ let ex5 = list_of_mylist(x) in # [1, 2, 3] #\n\n\n\ # All output from examples: #\n\ From bd3a3864b278a917ab00b1e2fb5073e9bec3eb57 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 6 Jan 2024 02:21:15 -0500 Subject: [PATCH 174/229] Switch nth's argument position --- src/haz3lcore/dynamics/Constraint.re | 2 +- src/haz3lcore/statics/ConstructorMap.re | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index 8174f6e816..da5ae548df 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -127,7 +127,7 @@ let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => switch (Typ.weak_head_normalize(ctx, ty)) { | Sum(map) => let num_variants = ConstructorMap.cardinal(map); - switch (ConstructorMap.nth(name, map)) { + switch (ConstructorMap.nth(map, name)) { | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) | None => Falsity // TODO: review }; diff --git a/src/haz3lcore/statics/ConstructorMap.re b/src/haz3lcore/statics/ConstructorMap.re index f871173adc..a350d16d92 100644 --- a/src/haz3lcore/statics/ConstructorMap.re +++ b/src/haz3lcore/statics/ConstructorMap.re @@ -100,7 +100,7 @@ let rec is_ground = (is_ground_value: 'a => bool, map: t('a)): bool => is_ground_value(head) && tail |> is_ground(is_ground_value) }; -let nth = (ctr: Constructor.t, map: t('a)): option(int) => { +let nth = (map: t('a), ctr: Constructor.t): option(int) => { // TODO: use List.find_index instead, which is available for OCaml 5.1 let ctrs_sorted = map |> sort |> ctrs_of; List.find_opt( From dca454f60baa6ef3db6b095b902ac7e190ce9384 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 6 Jan 2024 03:13:50 -0500 Subject: [PATCH 175/229] Constraint emission for synthesized Ap pattern --- src/haz3lcore/dynamics/Constraint.re | 32 +++++++++++++++++++--------- src/haz3lcore/statics/Statics.re | 6 ++++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/haz3lcore/dynamics/Constraint.re b/src/haz3lcore/dynamics/Constraint.re index da5ae548df..a56f435e55 100644 --- a/src/haz3lcore/dynamics/Constraint.re +++ b/src/haz3lcore/dynamics/Constraint.re @@ -109,7 +109,6 @@ let rec or_constraints = (lst: list(t)): t => | [xi, ...xis] => Or(xi, or_constraints(xis)) }; -// Temporary name let rec ctr_of_nth_variant = (num_variants, nth): (t => t) => if (num_variants == 1) { Fun.id; @@ -119,23 +118,36 @@ let rec ctr_of_nth_variant = (num_variants, nth): (t => t) => xi => InjR(xi |> ctr_of_nth_variant(num_variants - 1, nth - 1)); }; -let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t): t => +let of_ap = (ctx, mode, ctr: option(Constructor.t), arg: t, syn_ty): t => switch (ctr) { | Some(name) => - switch (mode) { - | Mode.Ana(ty) => + let ty = + switch (mode) { + | Mode.Ana(ty) => Some(ty) + | Syn => syn_ty + | _ => None + }; + switch (ty) { + | Some(ty) => switch (Typ.weak_head_normalize(ctx, ty)) { | Sum(map) => let num_variants = ConstructorMap.cardinal(map); switch (ConstructorMap.nth(map, name)) { | Some(nth) => arg |> ctr_of_nth_variant(num_variants, nth) - | None => Falsity // TODO: review + | None => Falsity }; - | _ => Falsity // TODO: review + | _ => Falsity } - | _ => Falsity // TODO: review - } - | None => Falsity // TODO: review + | None => Falsity + }; + | None => Falsity }; -let of_ctr = (ctx, mode, name) => of_ap(ctx, mode, Some(name), Truth); +let of_ctr = (ctx, mode, name, self) => { + let syn_ty = + switch (self) { + | Self.IsConstructor({syn_ty, _}) => syn_ty + | _ => assert(false) // impossible + }; + of_ap(ctx, mode, Some(name), Truth, syn_ty); +}; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6d7aac4169..e927649956 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -525,7 +525,8 @@ and upat_to_info_map = let (p, m) = go(~ctx, ~mode, p, m); add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => - atomic(Self.of_ctr(ctx, ctr), Constraint.of_ctr(ctx, mode, ctr)) + let self = Self.of_ctr(ctx, ctr); + atomic(self, Constraint.of_ctr(ctx, mode, ctr, self)); | Ap(fn, arg) => let ctr = UPat.ctr_name(fn); let fn_mode = Mode.of_ap(ctx, mode, ctr); @@ -535,7 +536,8 @@ and upat_to_info_map = add( ~self=Just(ty_out), ~ctx=arg.ctx, - ~constraint_=Constraint.of_ap(ctx, mode, ctr, arg.constraint_), + ~constraint_= + Constraint.of_ap(ctx, mode, ctr, arg.constraint_, Some(ty_out)), m, ); | TypeAnn(p, ann) => From c8c00e6565b8c0bd3169a064b9c9e17ba0db435a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 16 Jan 2024 09:51:23 -0500 Subject: [PATCH 176/229] Fixed inf recursion bug --- src/haz3lcore/statics/Info.re | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 84d8e21622..296fe47976 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -475,9 +475,9 @@ let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => let fixed_constraint_pat = (ctx, mode: Mode.t, self: Self.pat, constraint_: Constraint.t) : Constraint.t => - switch (status_pat(ctx, mode, self)) { - | InHole(_) => Constraint.Hole - | NotInHole(_) => constraint_ + switch (fixed_typ_pat(ctx, mode, self)) { + | Unknown(_) => Constraint.Hole + | _ => constraint_ }; let fixed_typ_exp = (ctx, mode: Mode.t, self: Self.exp): Typ.t => From 42266ceb1e4d6959fafbb5da72d160cc6294dc3b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Thu, 18 Jan 2024 18:22:17 -0500 Subject: [PATCH 177/229] Fixed overwritten-map bug --- src/haz3lcore/statics/Statics.re | 57 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 3a92c49722..d9be5dc2ff 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -304,20 +304,42 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - let (ps', m, final_constraint) = + let (ps', m) = + map_m( + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Mode.Ana(scrut.ty), + ), + ps, + m, + ); + let p_ctxs = List.map(Info.pat_ctx, ps'); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, + ); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + /* Add co-ctxs to patterns */ + let (m, final_constraint) = List.fold_left( - ((ps', m, acc_constraint), p) => { + ((m, acc_constraint), (p, co_ctx)) => { let (p, m) = go_pat( ~is_synswitch=false, - ~co_ctx=CoCtx.empty, + ~co_ctx, ~mode=Mode.Ana(scrut.ty), p, m, ); let p_constraint = Info.pat_constraint(p); if (!Incon.is_redundant(p_constraint, acc_constraint)) { - (ps' @ [p], m, Constraint.Or(p_constraint, acc_constraint)); + (m, Constraint.Or(p_constraint, acc_constraint)); } else { let info = Info.derived_pat( @@ -332,39 +354,14 @@ and uexp_to_info_map = ~constraint_=p_constraint, ); ( - ps' @ [info], // Override the info for the single upat add_info(p.term.ids, InfoPat(info), m), acc_constraint // Redundant patterns are ignored ); }; }, - ([], m, Constraint.Falsity), - ps, - ); - let p_ctxs = List.map(Info.pat_ctx, ps'); - let (es, m) = - List.fold_left2( - ((es, m), e, ctx) => - go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), - ([], m), - es, - p_ctxs, - ); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - /* Add co-ctxs to patterns */ - let (_, m) = - map_m( - ((p, co_ctx)) => - go_pat( - ~is_synswitch=false, - ~co_ctx, - ~mode=Mode.Ana(scrut.ty), - p, - ), + (m, Constraint.Falsity), List.combine(ps, e_co_ctxs), - m, ); (es, e_co_ctxs, branch_ids, final_constraint, m); }; From 493cdc7149280e69e99e07e0904b7077500f4a53 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 10:07:16 -0500 Subject: [PATCH 178/229] Resolve merge conflicts --- src/haz3lweb/view/Deco.re | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/haz3lweb/view/Deco.re b/src/haz3lweb/view/Deco.re index 3c79f6376f..e5cfacc04d 100644 --- a/src/haz3lweb/view/Deco.re +++ b/src/haz3lweb/view/Deco.re @@ -277,36 +277,6 @@ module Deco = }; // faster infomap traversal - let err_holes = (_z: Zipper.t) => { - let is_rep = (id: Id.t) => - switch (Id.Map.find_opt(id, M.terms)) { - | None => false - | Some(term) => id == Term.rep_id(term) - }; - Id.Map.fold( - (id, info, acc) => - /* Because of artefacts in Maketerm ID handling, - * there are be situations where ids appear in the - * info_map which do not occur in term_ranges. These - * ids should be purely duplicative, so skipping them - * when iterating over the info_map should have no - * effect, beyond supressing the resulting Not_found exs */ - switch (Id.Map.find_opt(id, M.term_ranges)) { - /* Without filtering out non-rep ids, there will be - * multiple error holes wrapping around a case expression - * or a list literal that has at least one comma, since the - * rules of case expressions and the inner commas of list - * literals are technically different forms */ - | Some(_) when is_rep(id) && Info.is_error(info) => [ - term_highlight(~clss=["err-hole"], id), - ...acc, - ] - | _ => acc - }, - M.info_map, - [], - ); - }; let err_holes = (_z: Zipper.t) => List.map(term_highlight(~clss=["err-hole"]), M.error_ids); From 129fcf25e2152fcc579bafe8ff9b6499738086f4 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 11:00:57 -0500 Subject: [PATCH 179/229] Generalize frontend, part I --- src/haz3lweb/view/CursorInspector.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 2b8ec57578..b04c9cf1e8 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -175,7 +175,7 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => | None => div_err([text("Case expression is inexhaustive")]) | Some(err) => div_err([ - exp_view(Exp(Match), InHole(Common(err))), + exp_view(cls, InHole(Common(err))), text("; case expression is inexhaustive"), ]) } From 51dec0320a3c29cc0a2b70a2effe3dd43c849fac Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 13:43:26 -0500 Subject: [PATCH 180/229] Inexhaustive self for functions --- src/haz3lcore/statics/Statics.re | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 9217cf4f86..918882a1ce 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -306,11 +306,12 @@ and uexp_to_info_map = /* add co_ctx to pattern */ let (p, m) = go_pat(~is_synswitch=false, ~co_ctx=e.co_ctx, ~mode=mode_pat, p, m); - add( - ~self=Just(Arrow(p.ty, e.ty)), - ~co_ctx=CoCtx.mk(ctx, p.ctx, e.co_ctx), - m, - ); + // TODO: factor out code + let unwrapped_self: Self.exp = Common(Just(Arrow(p.ty, e.ty))); + let is_exhaustive = p |> Info.pat_constraint |> Incon.is_exhaustive; + let self = + is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + add'(~self, ~co_ctx=CoCtx.mk(ctx, p.ctx, e.co_ctx), m); | Let(p, def, body) => let (p_syn, _) = go_pat(~is_synswitch=true, ~co_ctx=CoCtx.empty, ~mode=Syn, p, m); From c47bc6610559e3cf148d1f0ed253e36ebef185ee Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 17:46:04 -0500 Subject: [PATCH 181/229] Inexhaustive self for let expressions --- src/haz3lcore/statics/Statics.re | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 918882a1ce..17bba316e8 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -336,8 +336,13 @@ and uexp_to_info_map = p, m, ); - add( - ~self=Just(body.ty), + // TODO: factor out code + let unwrapped_self: Self.exp = Common(Just(body.ty)); + let is_exhaustive = p_ana |> Info.pat_constraint |> Incon.is_exhaustive; + let self = + is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + add'( + ~self, ~co_ctx= CoCtx.union([def.co_ctx, CoCtx.mk(ctx, p_ana.ctx, body.co_ctx)]), m, From d35b283d70ddcdcd8b0abb9aea37c4808460e305 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 18:15:40 -0500 Subject: [PATCH 182/229] Fixed TypeAnn escape checking bug --- src/haz3lcore/statics/Info.re | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index fe40e0456d..c7462ccac5 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -516,11 +516,21 @@ let fixed_typ_pat = (ctx, mode: Mode.t, self: Self.pat): Typ.t => { }; let fixed_constraint_pat = - (ctx, mode: Mode.t, self: Self.pat, constraint_: Constraint.t) + ( + upat: UPat.t, + ctx, + mode: Mode.t, + self: Self.pat, + constraint_: Constraint.t, + ) : Constraint.t => - switch (fixed_typ_pat(ctx, mode, self)) { - | Unknown(_) => Constraint.Hole - | _ => constraint_ + switch (upat.term) { + | TypeAnn(_) => constraint_ + | _ => + switch (fixed_typ_pat(ctx, mode, self)) { + | Unknown(_) => Constraint.Hole + | _ => constraint_ + } }; let fixed_typ_exp = (ctx, mode: Mode.t, self: Self.exp): Typ.t => @@ -545,7 +555,7 @@ let derived_pat = let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - let constraint_ = fixed_constraint_pat(ctx, mode, self, constraint_); + let constraint_ = fixed_constraint_pat(upat, ctx, mode, self, constraint_); { cls, self, From a53f02d2eac8e6561868a2bbadbeb2e8dc25a1a8 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 13 Feb 2024 18:37:40 -0500 Subject: [PATCH 183/229] Update CursorInspector.re --- src/haz3lweb/view/CursorInspector.re | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/haz3lweb/view/CursorInspector.re b/src/haz3lweb/view/CursorInspector.re index 6070b73bf0..af2d14918e 100644 --- a/src/haz3lweb/view/CursorInspector.re +++ b/src/haz3lweb/view/CursorInspector.re @@ -171,14 +171,16 @@ let rec exp_view = (cls: Term.Cls.t, status: Info.status_exp) => | InHole(FreeVariable(name)) => div_err([code_err(name), text("not found")]) | InHole(InexhaustiveMatch(additional_err)) => + let cls_str = Term.Cls.show(cls); switch (additional_err) { - | None => div_err([text("Case expression is inexhaustive")]) + | None => div_err([text(cls_str ++ " is inexhaustive")]) | Some(err) => + let cls_str = String.uncapitalize_ascii(cls_str); div_err([ exp_view(cls, InHole(Common(err))), - text("; case expression is inexhaustive"), - ]) - } + text("; " ++ cls_str ++ " is inexhaustive"), + ]); + }; | InHole(Common(error)) => div_err(common_err_view(cls, error)) | NotInHole(ok) => div_ok(common_ok_view(cls, ok)) }; From b63825dd99a285294a1163759a479bb3cc7db9cf Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 18 Mar 2024 02:01:37 -0400 Subject: [PATCH 184/229] Fix InvalidBoxedTypFun error on indeterminate argument in function position. --- src/haz3lcore/dynamics/Transition.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Transition.re b/src/haz3lcore/dynamics/Transition.re index b6ed2d2519..b8750ec31e 100644 --- a/src/haz3lcore/dynamics/Transition.re +++ b/src/haz3lcore/dynamics/Transition.re @@ -262,7 +262,7 @@ module Transition = (EV: EV_MODE) => { }); | TypAp(d, tau) => let. _ = otherwise(env, d => TypAp(d, tau)) - and. d' = req_final(req(state, env), d => TypAp(d, tau), d); + and. d' = req_value(req(state, env), d => TypAp(d, tau), d); switch (d') { | TypFun(utpat, tfbody) => /* Rule ITTLam */ From a7232e9d55229961eed1f02561e6fcc239f91486 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 18 Mar 2024 02:28:04 -0400 Subject: [PATCH 185/229] Fixed error of type applications' type not getting proper Info. --- src/haz3lcore/statics/Statics.re | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 260981b086..b86f42f2b0 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -300,13 +300,14 @@ and uexp_to_info_map = add(~self, ~co_ctx=CoCtx.union([fn.co_ctx, arg.co_ctx]), m); | TypAp(fn, utyp) => let typfn_mode = Mode.typap_mode; - let (fn, m_fn) = go(~mode=typfn_mode, fn, m); + let (fn, m) = go(~mode=typfn_mode, fn, m); + let (_, m) = utyp_to_info_map(~ctx, ~ancestors, utyp, m); let (option_name, ty_body) = Typ.matched_forall(ctx, fn.ty); let ty = Term.UTyp.to_typ(ctx, utyp); switch (option_name) { | Some(name) => - add(~self=Just(Typ.subst(ty, name, ty_body)), ~co_ctx=fn.co_ctx, m_fn) - | None => add(~self=Just(ty_body), ~co_ctx=fn.co_ctx, m_fn) /* invalid name matches with no free type variables. */ + add(~self=Just(Typ.subst(ty, name, ty_body)), ~co_ctx=fn.co_ctx, m) + | None => add(~self=Just(ty_body), ~co_ctx=fn.co_ctx, m) /* invalid name matches with no free type variables. */ }; | Fun(p, e) => let (mode_pat, mode_body) = Mode.of_arrow(ctx, mode); From b0396a77057ba84a3afaed34872b3f1a0ee42fe4 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 19 Mar 2024 15:56:36 -0400 Subject: [PATCH 186/229] Fix unresolved merge error (oops) --- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 23 ++------------------ 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 07999aa7ae..491eba6503 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -552,28 +552,7 @@ let mk = List.filter(x => !List.mem(x, bindings), next_recent_subst), Fun, ) -<<<<<<< HEAD - @ [ - DHDoc_common.Delim.arrow_Fun, - space(), - body_doc |> DHDoc_common.pad_child(~enforce_inline=false), - ], - ); - } else { - switch (s) { - | None => annot(DHAnnot.Collapsed, text("")) - | Some(name) => annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")) - }; - } - | TypFun(_tpat, _dbody) => - annot(DHAnnot.Collapsed, text("")) - | Fun(dp, ty, dbody, s) => - if (settings.show_fn_bodies) { - let bindings = DHPat.bound_vars(dp); - let body_doc = -======= | _ => ->>>>>>> dev go_formattable( dbody, ~env=ClosureEnvironment.without_keys(bindings, env), @@ -619,6 +598,8 @@ let mk = | Some(name) => name }; annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")); + | TypFun(_tpat, _dbody) => + annot(DHAnnot.Collapsed, text("")) | FixF(x, ty, dbody) when settings.show_fn_bodies && settings.show_fixpoints => let doc_body = From 1b48eedb96ed79f9ccd92022253b8fa009d75932 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 21 Mar 2024 13:01:56 -0400 Subject: [PATCH 187/229] Improve explainthis for type functions / applications. --- src/haz3lweb/explainthis/data/TypAppExp.re | 9 ++++++--- src/haz3lweb/explainthis/data/TypFunctionExp.re | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/haz3lweb/explainthis/data/TypAppExp.re b/src/haz3lweb/explainthis/data/TypAppExp.re index 84c2734d21..70acb8986a 100644 --- a/src/haz3lweb/explainthis/data/TypAppExp.re +++ b/src/haz3lweb/explainthis/data/TypAppExp.re @@ -4,11 +4,14 @@ open Example; let typfunapp_exp_ex = { sub_id: TypFunAp, - term: mk_example("(typfun X -> (fun x : X -> x))@"), - message: "The polymorphic identity function is instantiated at Int. The type variable X is bound to Int in the type function body and the body evaluates to the identity function on integers.", + term: + mk_example( + "let id : \n forall a -> (a -> a) = \n typfun a -> \n fun x : a -> x \n in id@" + ), + message: "The polymorphic identity function is instantiated at Int. The type variable a is bound to Int in the type function body and the body evaluates to the identity function on integers.", }; let _exp_tfun = exp("e_tfun"); -let _typ = typ("_typ"); +let _typ = typ("ty"); let typfunapp_exp_coloring_ids = (~f_id: Id.t, ~typ_id: Id.t): list((Id.t, Id.t)) => [ (Piece.id(_exp_tfun), f_id), diff --git a/src/haz3lweb/explainthis/data/TypFunctionExp.re b/src/haz3lweb/explainthis/data/TypFunctionExp.re index 6c979c3116..93b7300b18 100644 --- a/src/haz3lweb/explainthis/data/TypFunctionExp.re +++ b/src/haz3lweb/explainthis/data/TypFunctionExp.re @@ -6,16 +6,16 @@ let poly_id_ex = { sub_id: TypFun(Basic), term: mk_example( - "let id : \n forall X -> (X -> X) = \n typfun X -> \n fun x : X -> x \n in id", + "let id : \n forall a -> (a -> a) = \n typfun a -> \n fun x : a -> x \n in id", ), - message: "The polymorphic identity function. It may be instantiated at any type X, after which the function acts as type (X -> X).", + message: "The polymorphic identity function. It may be instantiated at any type a, after which the function acts as type (a -> a).", }; -let _tp = tpat("X"); +let _tp = tpat("a"); let _exp = exp("e"); let typfun_var: form = { let explanation = "When applied to a type that which is bound to the [*type variable*](%s), evaluates to the type function [*body*](%s)."; - let form = [mk_fun([[space(), _tp, space()]]), space(), _exp]; + let form = [mk_typfun([[space(), _tp, space()]]), space(), _exp]; { id: TypFunctionExp, syntactic_form: form, From 0e640cdb95d4c1cf83d90835de0efde65db6c507 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 21 Mar 2024 13:11:06 -0400 Subject: [PATCH 188/229] Add indent after typfun. --- src/haz3lcore/Measured.re | 4 +++- src/haz3lweb/explainthis/data/TypAppExp.re | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/Measured.re b/src/haz3lcore/Measured.re index 747f88e204..5ed9d0264d 100644 --- a/src/haz3lcore/Measured.re +++ b/src/haz3lcore/Measured.re @@ -233,7 +233,9 @@ let post_tile_indent = (t: Tile.t) => { let complete_fun = Tile.is_complete(t) && ( - t.label == Form.get("fun_").label || t.label == Form.get("if_").label + t.label == Form.get("fun_").label + || t.label == Form.get("typfun").label + || t.label == Form.get("if_").label ); let missing_right_extreme = Tile.r_shard(t) < List.length(t.label) - 1; complete_fun || missing_right_extreme; diff --git a/src/haz3lweb/explainthis/data/TypAppExp.re b/src/haz3lweb/explainthis/data/TypAppExp.re index 70acb8986a..5b1ad13106 100644 --- a/src/haz3lweb/explainthis/data/TypAppExp.re +++ b/src/haz3lweb/explainthis/data/TypAppExp.re @@ -4,9 +4,9 @@ open Example; let typfunapp_exp_ex = { sub_id: TypFunAp, - term: + term: mk_example( - "let id : \n forall a -> (a -> a) = \n typfun a -> \n fun x : a -> x \n in id@" + "let id : \n forall a -> (a -> a) = \n typfun a -> \n fun x : a -> x \n in id@", ), message: "The polymorphic identity function is instantiated at Int. The type variable a is bound to Int in the type function body and the body evaluates to the identity function on integers.", }; From 8890e4cb0449a66b1c6c19311fde28fb531e4c6e Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 21 Mar 2024 23:03:59 -0400 Subject: [PATCH 189/229] Add name to data record for dhexp typfuns. --- src/haz3lcore/dynamics/DH.re | 17 ++++++++--------- src/haz3lcore/dynamics/Elaborator.re | 4 ++-- src/haz3lcore/dynamics/EvaluatorPost.re | 10 +++++----- src/haz3lcore/dynamics/FilterMatcher.re | 4 ++-- src/haz3lcore/dynamics/PatternMatch.re | 4 ++-- src/haz3lcore/dynamics/Substitution.re | 2 +- src/haz3lcore/dynamics/Transition.re | 2 +- src/haz3lschool/SyntaxTest.re | 2 ++ src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 13 ++++++++++++- 9 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index 672743d9ac..42271935b6 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -21,7 +21,7 @@ module rec DHExp: { | Let(DHPat.t, t, t) | FixF(Var.t, Typ.t, t) | Fun(DHPat.t, Typ.t, t, option(Var.t)) - | TypFun(Term.UTPat.t, t) + | TypFun(Term.UTPat.t, t, option(Var.t)) | TypAp(t, Typ.t) | Ap(t, t) | ApBuiltin(string, t) @@ -82,7 +82,7 @@ module rec DHExp: { | Let(DHPat.t, t, t) | FixF(Var.t, Typ.t, t) | Fun(DHPat.t, Typ.t, t, option(Var.t)) - | TypFun(Term.UTPat.t, t) + | TypFun(Term.UTPat.t, t, option(Var.t)) | TypAp(t, Typ.t) | Ap(t, t) | ApBuiltin(string, t) @@ -186,7 +186,7 @@ module rec DHExp: { | Let(dp, b, c) => Let(dp, strip_casts(b), strip_casts(c)) | FixF(a, b, c) => FixF(a, b, strip_casts(c)) | Fun(a, b, c, d) => Fun(a, b, strip_casts(c), d) - | TypFun(a, b) => TypFun(a, strip_casts(b)) + | TypFun(a, b, c) => TypFun(a, strip_casts(b), c) | Ap(a, b) => Ap(strip_casts(a), strip_casts(b)) | TypAp(a, b) => TypAp(strip_casts(a), b) | Test(id, a) => Test(id, strip_casts(a)) @@ -251,9 +251,8 @@ module rec DHExp: { f1 == f2 && ty1 == ty2 && fast_equal(d1, d2) | (Fun(dp1, ty1, d1, s1), Fun(dp2, ty2, d2, s2)) => dp1 == dp2 && ty1 == ty2 && fast_equal(d1, d2) && s1 == s2 - | (TypFun(_tpat1, d1), TypFun(_tpat2, d2)) => - // TODO (poly) - fast_equal(d1, d2) + | (TypFun(_tpat1, d1, s1), TypFun(_tpat2, d2, s2)) => + _tpat1 == _tpat2 && fast_equal(d1, d2) && s1 == s2 | (TypAp(d1, ty1), TypAp(d2, ty2)) => fast_equal(d1, d2) && ty1 == ty2 | (Ap(d11, d21), Ap(d12, d22)) | (Cons(d11, d21), Cons(d12, d22)) => @@ -358,7 +357,7 @@ module rec DHExp: { && i1 == i2; }; - let rec ty_subst = (s: Typ.t, x: TypVar.t, exp): t => { + let rec ty_subst = (s: Typ.t, x: TypVar.t, exp: DHExp.t): t => { let re = e2 => ty_subst(s, x, e2); let t_re = ty => Typ.subst(s, x, ty); switch (exp) { @@ -368,12 +367,12 @@ module rec DHExp: { | TypAp(tfun, ty) => TypAp(re(tfun), t_re(ty)) | ListLit(mv, mvi, t, lst) => ListLit(mv, mvi, t_re(t), List.map(re, lst)) - | TypFun(utpat, body) => + | TypFun(utpat, body, var) => switch (Term.UTPat.tyvar_of_utpat(utpat)) { | Some(x') when x == x' => exp | _ => /* Note that we do not have to worry about capture avoidance, since s will always be closed. */ - TypFun(utpat, re(body)) + TypFun(utpat, re(body), var) } | NonEmptyHole(errstat, mv, hid, t) => NonEmptyHole(errstat, mv, hid, re(t)) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 6ff513162b..1911afd5ed 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -172,9 +172,8 @@ let rec dhexp_of_uexp = let+ ty = fixed_pat_typ(m, p); DHExp.Fun(dp, ty, d1, None); | TypFun(tpat, body) => - // TODO (typfun) let+ d1 = dhexp_of_uexp(m, body); - DHExp.TypFun(tpat, d1); + DHExp.TypFun(tpat, d1, None); | Tuple(es) => let+ ds = es |> List.map(dhexp_of_uexp(m)) |> OptUtil.sequence; DHExp.Tuple(ds); @@ -241,6 +240,7 @@ let rec dhexp_of_uexp = name => fun | Fun(p, ty, e, _) => DHExp.Fun(p, ty, e, name) + | TypFun(tpat, e, _) => DHExp.TypFun(tpat, e, name) | d => d ); let* dp = dhpat_of_upat(m, p); diff --git a/src/haz3lcore/dynamics/EvaluatorPost.re b/src/haz3lcore/dynamics/EvaluatorPost.re index bf770b9f8c..fd3453dac9 100644 --- a/src/haz3lcore/dynamics/EvaluatorPost.re +++ b/src/haz3lcore/dynamics/EvaluatorPost.re @@ -181,9 +181,9 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => let* d = pp_uneval(env, d); Fun(dp, ty, d, s) |> return; - | TypFun(tpat, d1) => + | TypFun(tpat, d1, s) => let* d1' = pp_uneval(env, d1); - TypFun(tpat, d1') |> return; + TypFun(tpat, d1', s) |> return; | Let(dp, d1, d2) => /* d1 should already be evaluated, d2 is not */ @@ -307,9 +307,9 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => let* d'' = pp_uneval(env, d'); Fun(dp, ty, d'', s) |> return; - | TypFun(tpat, d1) => + | TypFun(tpat, d1, s) => let* d1' = pp_uneval(env, d1); - TypFun(tpat, d1') |> return; + TypFun(tpat, d1', s) |> return; | Ap(d1, d2) => let* d1' = pp_uneval(env, d1); @@ -481,7 +481,7 @@ let rec track_children_of_hole = | Test(_, d) | FixF(_, _, d) | Fun(_, _, d, _) - | TypFun(_, d) + | TypFun(_, d, _) | TypAp(d, _) | Prj(d, _) | Cast(d, _, _) diff --git a/src/haz3lcore/dynamics/FilterMatcher.re b/src/haz3lcore/dynamics/FilterMatcher.re index 5ac853ebb6..62991a25ae 100644 --- a/src/haz3lcore/dynamics/FilterMatcher.re +++ b/src/haz3lcore/dynamics/FilterMatcher.re @@ -82,8 +82,8 @@ let rec matches_exp = | (BuiltinFun(dn), BuiltinFun(fn)) => dn == fn | (BuiltinFun(_), _) => false - | (TypFun(pat1, d1), TypFun(pat2, d2)) => - matches_utpat(pat1, pat2) && matches_exp(env, d1, d2) + | (TypFun(pat1, d1, s1), TypFun(pat2, d2, s2)) => + s1 == s2 && matches_utpat(pat1, pat2) && matches_exp(env, d1, d2) | (TypFun(_), _) => false | (Fun(dp1, dty1, d1, dname1), Fun(fp1, fty1, f1, fname1)) => diff --git a/src/haz3lcore/dynamics/PatternMatch.re b/src/haz3lcore/dynamics/PatternMatch.re index e6cd7cd7d9..779f685b5e 100644 --- a/src/haz3lcore/dynamics/PatternMatch.re +++ b/src/haz3lcore/dynamics/PatternMatch.re @@ -336,7 +336,7 @@ and matches_cast_Tuple = | ExpandingKeyword(_) => IndetMatch | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch - | TypFun(_, _) => DoesNotMatch + | TypFun(_, _, _) => DoesNotMatch | Fun(_, _, _, _) => DoesNotMatch | Closure(_, Fun(_)) => DoesNotMatch | Closure(_, _) => IndetMatch @@ -478,7 +478,7 @@ and matches_cast_Cons = | ExpandingKeyword(_) => IndetMatch | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch - | TypFun(_, _) => DoesNotMatch + | TypFun(_, _, _) => DoesNotMatch | Fun(_, _, _, _) => DoesNotMatch | Closure(_, d') => matches_cast_Cons(dp, d', elt_casts) | TypAp(_, _) => IndetMatch diff --git a/src/haz3lcore/dynamics/Substitution.re b/src/haz3lcore/dynamics/Substitution.re index 1a8d09f8a0..c4c92feed1 100644 --- a/src/haz3lcore/dynamics/Substitution.re +++ b/src/haz3lcore/dynamics/Substitution.re @@ -42,7 +42,7 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => let d3 = subst_var(d1, x, d3); Fun(dp, ty, d3, s); } - | TypFun(tpat, d3) => TypFun(tpat, subst_var(d1, x, d3)) + | TypFun(tpat, d3, s) => TypFun(tpat, subst_var(d1, x, d3), s) | Closure(env, d3) => /* Closure shouldn't appear during substitution (which only is called from elaboration currently) */ diff --git a/src/haz3lcore/dynamics/Transition.re b/src/haz3lcore/dynamics/Transition.re index 7f6d6c8fae..572cfd3920 100644 --- a/src/haz3lcore/dynamics/Transition.re +++ b/src/haz3lcore/dynamics/Transition.re @@ -276,7 +276,7 @@ module Transition = (EV: EV_MODE) => { let. _ = otherwise(env, d => TypAp(d, tau)) and. d' = req_value(req(state, env), d => TypAp(d, tau), d); switch (d') { - | TypFun(utpat, tfbody) => + | TypFun(utpat, tfbody, _) => /* Rule ITTLam */ switch (Term.UTPat.tyvar_of_utpat(utpat)) { | Some(tyvar) => diff --git a/src/haz3lschool/SyntaxTest.re b/src/haz3lschool/SyntaxTest.re index f7125e28ab..ee97349eae 100644 --- a/src/haz3lschool/SyntaxTest.re +++ b/src/haz3lschool/SyntaxTest.re @@ -294,6 +294,8 @@ let rec var_mention = (name: string, uexp: Term.UExp.t): bool => { | Let(p, def, body) => var_mention_upat(name, p) ? false : var_mention(name, def) || var_mention(name, body) + | TypFun(_, u) + | TypAp(u, _) | Test(u) | Parens(u) | UnOp(_, u) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 491eba6503..1316a73bf5 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -599,7 +599,18 @@ let mk = }; annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")); | TypFun(_tpat, _dbody) => - annot(DHAnnot.Collapsed, text("")) + /* same display as with Fun but with anon typfn in the nameless case. */ + let name = + switch (s) { + | None => "anon typfn" + | Some(name) + when + !settings.show_fixpoints + && String.ends_with(~suffix="+", name) => + String.sub(name, 0, String.length(name) - 1) + | Some(name) => name + }; + annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")); | FixF(x, ty, dbody) when settings.show_fn_bodies && settings.show_fixpoints => let doc_body = From 4f52a4d201ec6effe30682d85ec468b0f06b9873 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Thu, 21 Mar 2024 23:16:14 -0400 Subject: [PATCH 190/229] Fix a few remaining errors. --- src/haz3lschool/SyntaxTest.re | 114 +------------------ src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 2 +- 2 files changed, 7 insertions(+), 109 deletions(-) diff --git a/src/haz3lschool/SyntaxTest.re b/src/haz3lschool/SyntaxTest.re index ee97349eae..6127d1d5b2 100644 --- a/src/haz3lschool/SyntaxTest.re +++ b/src/haz3lschool/SyntaxTest.re @@ -37,114 +37,6 @@ let rec find_var_upat = (name: string, upat: Term.UPat.t): bool => { }; }; -let rec var_mention = (name: string, uexp: Term.UExp.t): bool => { - switch (uexp.term) { - | Var(x) => x == name - | EmptyHole - | Triv - | Invalid(_) - | MultiHole(_) - | Bool(_) - | Int(_) - | Float(_) - | String(_) - | Constructor(_) => false - | Fun(args, body) => - find_var_upat(name, args) ? false : var_mention(name, body) - | ListLit(l) - | Tuple(l) => - List.fold_left((acc, ue) => {acc || var_mention(name, ue)}, false, l) - | Let(p, def, body) => - find_var_upat(name, p) - ? false : var_mention(name, def) || var_mention(name, body) - | TypFun(_, u) - | TypAp(u, _) - | Test(u) - | Parens(u) - | UnOp(_, u) - | TyAlias(_, _, u) - | Filter(_, _, u) => var_mention(name, u) - | Ap(u1, u2) - | Pipeline(u1, u2) - | Seq(u1, u2) - | Cons(u1, u2) - | ListConcat(u1, u2) - | BinOp(_, u1, u2) => var_mention(name, u1) || var_mention(name, u2) - | If(u1, u2, u3) => - var_mention(name, u1) || var_mention(name, u2) || var_mention(name, u3) - | Match(g, l) => - var_mention(name, g) - || List.fold_left( - (acc, pe) => { - let (p, e) = pe; - find_var_upat(name, p) ? false : acc || var_mention(name, e); - }, - false, - l, - ) - }; -}; - -let rec var_applied = (name: string, uexp: Term.UExp.t): bool => { - switch (uexp.term) { - | Var(_) - | EmptyHole - | Triv - | Invalid(_) - | MultiHole(_) - | Bool(_) - | Int(_) - | Float(_) - | String(_) - | Constructor(_) => false - | Fun(args, body) => - find_var_upat(name, args) ? false : var_applied(name, body) - | ListLit(l) - | Tuple(l) => - List.fold_left((acc, ue) => {acc || var_applied(name, ue)}, false, l) - | Let(p, def, body) => - find_var_upat(name, p) - ? false : var_applied(name, def) || var_applied(name, body) - | TypFun(_, u) - | Test(u) - | Parens(u) - | UnOp(_, u) - | TyAlias(_, _, u) - | Filter(_, _, u) => var_applied(name, u) - | TypAp(u, _) => - switch (u.term) { - | Var(x) => x == name ? true : false - | _ => var_applied(name, u) - } - | Ap(u1, u2) => - switch (u1.term) { - | Var(x) => x == name ? true : var_applied(name, u2) - | _ => var_applied(name, u1) || var_applied(name, u2) - } - | Pipeline(u1, u2) => - switch (u2.term) { - | Var(x) => x == name ? true : var_applied(name, u1) - | _ => var_applied(name, u1) || var_applied(name, u2) - } - | Cons(u1, u2) - | Seq(u1, u2) - | ListConcat(u1, u2) - | BinOp(_, u1, u2) => var_applied(name, u1) || var_applied(name, u2) - | If(u1, u2, u3) => - var_applied(name, u1) || var_applied(name, u2) || var_applied(name, u3) - | Match(g, l) => - var_applied(name, g) - || List.fold_left( - (acc, pe) => { - let (p, e) = pe; - find_var_upat(name, p) ? false : acc || var_applied(name, e); - }, - false, - l, - ) - }; -}; - /* Helper function used in the function find_fn which takes the pattern (upat) and the definition (def) of a let expression and @@ -346,11 +238,17 @@ let rec var_applied = (name: string, uexp: Term.UExp.t): bool => { | Let(p, def, body) => var_mention_upat(name, p) ? false : var_applied(name, def) || var_applied(name, body) + | TypFun(_, u) | Test(u) | Parens(u) | UnOp(_, u) | TyAlias(_, _, u) | Filter(_, _, u) => var_applied(name, u) + | TypAp(u, _) => + switch (u.term) { + | Var(x) => x == name ? true : false + | _ => var_applied(name, u) + } | Ap(u1, u2) => switch (u1.term) { | Var(x) => x == name ? true : var_applied(name, u2) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 1316a73bf5..d786cc5984 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -598,7 +598,7 @@ let mk = | Some(name) => name }; annot(DHAnnot.Collapsed, text("<" ++ name ++ ">")); - | TypFun(_tpat, _dbody) => + | TypFun(_tpat, _dbody, s) => /* same display as with Fun but with anon typfn in the nameless case. */ let name = switch (s) { From 8fe137d09d7e2fce42ef445cae34ed8cbf6a8e00 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Fri, 22 Mar 2024 17:48:22 -0400 Subject: [PATCH 191/229] Add polymorphism to Documentation > Basic Reference. --- src/haz3lweb/Init.ml | 595 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 592 insertions(+), 3 deletions(-) diff --git a/src/haz3lweb/Init.ml b/src/haz3lweb/Init.ml index 4b67fd8596..84116e2fe6 100644 --- a/src/haz3lweb/Init.ml +++ b/src/haz3lweb/Init.ml @@ -8589,7 +8589,7 @@ let startup : PersistentData.t = { zipper = "((selection((focus Left)(content())(mode \ - Normal)))(backpack())(relatives((siblings(((Secondary((id \ + Normal)))(backpack())(relatives((siblings(()((Secondary((id \ c02465e1-d580-455a-aa60-b6aeb9216493)(content(Comment\"# \ Hazel Language Quick Reference #\"))))(Secondary((id \ eac6ad58-e3bb-434f-9db0-2e8fd6072393)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ @@ -10228,7 +10228,580 @@ let startup : PersistentData.t = \"))))(Secondary((id \ ba102ddc-ef92-487c-b01f-3e1dc2efa6c2)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ 33dd8e04-138e-4c10-a0d3-21170aac493f)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ - d74ffc8b-d059-4d7a-9e68-c03ea87db97d)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + 9991f3a8-0275-4b2d-b84b-dc1f08b7f0c0)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + b90baab9-f7d3-4fbb-addd-99040020a2d6)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ + edfce7ce-180d-431a-b9b2-a2e7a51639ef)(content(Comment\"# \ + Polymorphic Functions #\"))))(Secondary((id \ + d74ffc8b-d059-4d7a-9e68-c03ea87db97d)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + be30a708-71f1-4d22-b019-f2fa6a852c36)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 17))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + ccf15e74-30da-475b-a0c2-478d1625f8bf)(content(Whitespace\" \ + \"))))(Tile((id \ + b7f6dd49-e74e-47e0-9442-c67a9337c079)(label(poly_id))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + d3788600-3613-40f5-8a38-d4c3f512bd11)(content(Whitespace\" \ + \"))))(Tile((id \ + edc9de0a-0f75-46a9-b412-17ea5fbafe3f)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 25a95d9b-158a-4afc-9aee-a6f3663a5267)(content(Whitespace\" \ + \"))))(Tile((id \ + 6eea38a1-2acb-405c-b00a-175c767b094c)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 19b97957-796a-4a68-bed4-e9bacb1a438b)(content(Whitespace\" \ + \"))))(Tile((id \ + a9f2034f-6f84-43f1-825a-4222508c85ac)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 79e3788d-780b-44f3-bebc-bb7b72b6c4f6)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 330b36a2-7516-479c-b8d0-d3296ef52d22)(content(Whitespace\" \ + \"))))(Tile((id \ + aa180020-b296-4890-91d0-23b42ae036f5)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 07a039d0-ad3c-425a-8351-ea29333cbe86)(content(Whitespace\" \ + \"))))(Tile((id \ + dcb3a139-8a15-4ca5-804b-7790b2db8454)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + b546a9d7-62e6-4831-9951-02257cd8be0d)(content(Whitespace\" \ + \"))))(Tile((id \ + 29e8d470-5c3c-4446-a49d-1510641e1489)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 3c96f25f-b9b8-4a4d-bd88-970efe02a038)(content(Whitespace\" \ + \")))))((Secondary((id \ + ea0072f4-75ba-4373-8200-b1d1cbfa944d)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + a30494f3-c10f-449f-a47e-9cac67ec43e4)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 8b4c1606-1f5f-4619-b841-2bd570127056)(content(Whitespace\" \ + \"))))(Tile((id \ + 29351975-8dc7-455a-a313-eb4133370d9e)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 5fc9ced0-2b6f-4f95-98e8-e6871ee17cf8)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 0351c740-c538-4e10-b168-2a19621720cb)(content(Whitespace\" \ + \"))))(Tile((id \ + 3edfb2a6-ae95-424f-960b-3a8165db4d2a)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 4237578d-8437-47d1-8135-0dd226630c52)(content(Whitespace\" \ + \"))))(Tile((id \ + f1f49520-1f5c-4c42-8c1e-0afbd693de61)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 523cb91b-d643-4bce-aa48-7e75bfca2eb6)(content(Whitespace\" \ + \"))))(Tile((id \ + fe554f4e-89ee-4d69-b788-d78d5e43b0a4)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 77dc15d2-f278-43a4-a720-45082382fe8e)(content(Whitespace\" \ + \"))))(Tile((id \ + c86b754d-9643-4cc0-b5dc-de2074cc9486)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 3afe26ba-61a0-4712-8369-f75dba447c41)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + fceafefa-bde0-4f4a-8250-e480e42a456e)(content(Whitespace\" \ + \"))))(Tile((id \ + 821578a3-efe2-4747-968c-1af34fa66cd8)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 43e7a315-d368-4859-bb56-66839a8292e7)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 17810f4f-b62b-46e7-8613-a80821e1f896)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 547b939e-ffd6-46ff-929f-2b0e225fe9df)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 17))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + b66c0b83-c059-4925-b25f-9c23c0cc6413)(content(Whitespace\" \ + \"))))(Tile((id \ + 31be1813-03d0-4110-b37b-d710f5dcc43c)(label(apply_both))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 06a274cd-38db-4c54-98d8-69fe9c184c5e)(content(Whitespace\" \ + \"))))(Tile((id \ + 6ed96af6-8bf7-4fb1-b1e8-d2c9814299b1)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 9dd0b82e-5563-4cd3-a81d-069903c7b67b)(content(Whitespace\" \ + \"))))(Tile((id \ + 490bc44f-0166-4717-b032-82cffdddff56)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 1425337b-b260-4e7b-b37a-b8b6dcf8d34a)(content(Whitespace\" \ + \"))))(Tile((id \ + 832da6f4-dbd5-43ad-ac4c-cfe93abf8ea5)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + d46f7c08-56dd-4a91-a99a-4e9465f96c26)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + a502d207-63e7-4c91-80ad-5ff3a9db03e6)(content(Whitespace\" \ + \"))))(Tile((id \ + 4c3e1db6-5c4d-4594-8220-1f9c07d8357e)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 91b1a7e1-a477-4be0-89f2-6640bb6f9d0f)(content(Whitespace\" \ + \"))))(Tile((id \ + 84ff8f7c-f5e8-43a2-907f-614545ee7614)(label(b))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 51a93e99-b088-48da-8904-bf952381385c)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + d23b8939-dba3-4a78-b463-6ae659079d06)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 98703e4f-6c3e-4702-8684-564ad220603d)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 1569f18f-bf5b-4e0b-b373-0968d9c027a3)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 52872153-6dab-4f58-aafe-36daf66c1385)(content(Whitespace\" \ + \"))))(Tile((id \ + f11f90e4-ad88-4379-b935-aca0278995aa)(label(c))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 5b6cdedf-02b7-412e-9a23-2bcdefc0f4b0)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 78f728ff-af0b-4aa5-adf0-edb7af8dc68c)(content(Whitespace\" \ + \"))))(Tile((id \ + 4dcddeed-ee1e-4c65-b636-26ce6a4646ab)(label(c))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 4c82fe91-2252-4282-85e2-8b188cd8079c)(content(Whitespace\" \ + \"))))(Tile((id \ + 004a40c8-8e5b-4985-b0e2-9703a1ef0a94)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + c9ba11bb-0b6f-4fc7-8cf8-d979f001b850)(content(Whitespace\" \ + \"))))(Tile((id \ + 1601c6aa-0e48-49f2-a921-4d98f128ec7a)(label(c))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 50de9230-1cb3-4967-8e5d-2686ab33b797)(content(Whitespace\" \ + \"))))(Tile((id \ + a3015949-a4c0-4cd8-9346-6323090d0c55)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + a758f40e-83a9-42dc-b97e-38f432a461e6)(content(Whitespace\" \ + \"))))(Tile((id \ + 80d2b6e5-cc53-42e1-a34e-302cb24435bf)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 62d3e953-d36e-40a8-bb31-d3a1d29c9d25)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 129b9f69-db91-4538-a078-58f8eb5795e8)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 7370cc86-5f2d-480e-a154-aa2c09d32826)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 15))(sort \ + Typ))((shape(Concave 15))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + d94c8dc7-3d78-49a5-b93e-50d2b18af498)(content(Whitespace\" \ + \"))))(Tile((id \ + 0c251b37-e176-459c-bbfb-925cf7d09987)(label(b))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + bdb464cf-15d6-4023-84cc-fe983c5e8467)(content(Whitespace\" \ + \"))))(Tile((id \ + 79b66a41-0336-4baa-81c4-ef5e7107e431)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + d52538e2-1524-47a7-b72f-ff70dc2bf97d)(content(Whitespace\" \ + \"))))(Tile((id \ + baa44352-3f92-40d8-94ac-dcdb590fa503)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 6cb20c8f-1360-4b44-b423-56addbd92f44)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + 83172c4a-d27c-44f0-8fd0-3942f74e3635)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 15))(sort \ + Typ))((shape(Concave 15))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + ff148a90-409b-4903-97b3-5869b166b5f3)(content(Whitespace\" \ + \"))))(Tile((id \ + 07c72e86-9abe-415a-be06-5b9fa5f2adf8)(label(b))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children())))))))))))))(Secondary((id \ + b975b9e6-9750-4a57-8a27-499653bb604e)(content(Whitespace\" \ + \")))))((Secondary((id \ + 66e8dcdd-d358-4a3b-8d4c-c93140df5369)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + debae5ca-2828-4460-9307-929eb725736c)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 3144ba77-8417-456b-9345-0d6b5e7c590c)(content(Whitespace\" \ + \"))))(Tile((id \ + 35d9db9c-3710-47b1-997b-3dcea9b83b6e)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + b9f0d6e7-d029-455d-ac83-b17de4aa172e)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 8192adb7-ad34-4ab1-8844-0ab46b5c4771)(content(Whitespace\" \ + \"))))(Tile((id \ + aff9b212-bbe9-4333-a769-8caf2115d8de)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 25e1ce2d-c3c8-413a-8e9f-5e9792b44f1e)(content(Whitespace\" \ + \"))))(Tile((id \ + 7a612d19-b4bc-4d31-bfb0-cc7dbc80d5fe)(label(b))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + f26f75e0-b159-4e1b-805c-e405170e82f5)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + cc766fc6-23b5-4600-b2b2-082aac3a14b7)(content(Whitespace\" \ + \"))))(Tile((id \ + 01917c22-4fb2-4a0b-94f7-b244e9fbfda2)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 8f4768bf-6ca2-4f3f-b2f6-8038ad7d73dd)(content(Whitespace\" \ + \"))))(Tile((id \ + f7e1fe6d-3867-42e8-9fa5-99d50953da90)(label(f))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 54c5b743-ac18-4099-835f-666dc529f5cc)(content(Whitespace\" \ + \"))))(Tile((id \ + c55d17ae-d41f-461f-bf4f-4be94bd65762)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 33481f20-38ef-4609-ad30-d2b1833d9fd7)(content(Whitespace\" \ + \"))))(Tile((id \ + d27fd47d-eebc-4f61-b6e3-8b3ef398ec1c)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 651e3781-854e-4e7b-98bd-e3fa6cc6003f)(content(Whitespace\" \ + \"))))(Tile((id \ + 4b997e0a-bd24-4396-b8bc-aecdb8b036a5)(label(c))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + c352e753-c5ff-48de-8b59-0ec50c239e6e)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 796833a7-5f5b-42a6-bb69-8ae8d17fb133)(content(Whitespace\" \ + \"))))(Tile((id \ + 6545b7f1-f73e-422a-8435-a07c9da93673)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 8add133a-0bac-4b51-9946-8b321359410d)(label(c))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + 7cd03ffe-2c25-4828-b6f6-dbf473064a4c)(content(Whitespace\" \ + \"))))(Tile((id \ + 662e2713-f973-4583-9cc9-0790cbb04af4)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 7190604a-1045-4ce3-be03-e2a25c9ac980)(content(Whitespace\" \ + \"))))(Tile((id \ + 657cba03-c1df-436a-96a6-7de49ee86436)(label(c))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + b0264a1d-e50c-4ffa-9d11-0bc306f1e9a8)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 8c303280-adaa-402a-85ed-8fe1442c8903)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 184871c4-f611-4679-9af9-6d31f7d1c094)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 411cc97e-44aa-44e5-88f7-90d5f53924ab)(content(Whitespace\" \ + \"))))(Tile((id \ + 41df693e-7029-4f55-9048-63be308c4ef5)(label(\"(\"\")\"))(mold((out \ + Pat)(in_(Pat))(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0 1))(children(((Tile((id \ + 943e8fea-aee7-4392-b251-df60f3101e77)(label(x))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + 8eda0e7b-49cc-4234-b390-0d18d5444c55)(label(,))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 15))(sort \ + Pat))((shape(Concave 15))(sort \ + Pat))))))(shards(0))(children())))(Secondary((id \ + 9f925a0d-487f-4dab-bc1b-91b7c2b6d77d)(content(Whitespace\" \ + \"))))(Tile((id \ + c60b29e0-2207-4f8f-b2d6-4d318a896fb1)(label(y))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort \ + Pat))))))(shards(0))(children()))))))))(Secondary((id \ + 3fe52b30-bc25-4360-8e49-7d383c6d7630)(content(Whitespace\" \ + \"))))(Tile((id \ + 6b64f1db-59d9-427b-b91c-a9586a46a423)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 76ad5b97-a2a2-487a-8e08-ef95afdcfaba)(content(Whitespace\" \ + \"))))(Tile((id \ + 8fc5e79c-5af4-4a87-b340-e49d3a07108d)(label(\"(\"\")\"))(mold((out \ + Typ)(in_(Typ))(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0 1))(children(((Tile((id \ + 3981524e-b182-4229-9558-317c5e3b674e)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Tile((id \ + d1d74e3e-b370-448c-b8fa-a2a3354cd25d)(label(,))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 15))(sort \ + Typ))((shape(Concave 15))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 5f875c31-b3fe-4d3f-a673-fb0c4d82820c)(content(Whitespace\" \ + \"))))(Tile((id \ + dfc82e9a-f945-4b24-aa6f-72245f4a5c61)(label(b))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 131ac428-7dea-47f1-afd3-ef87d2185aaa)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + f4c1b938-fc33-417a-b232-08b15a775042)(content(Whitespace\" \ + \"))))(Tile((id \ + b3ddaea7-5ebf-4049-bb7b-608b9bb0403c)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2e7b5910-8655-4268-a6c4-e7c7785b6e26)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + b5cf1c4e-0da5-4b49-bb26-4f50f5f3e629)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + c7950c78-5a3d-4088-9b03-0a2af7dc6e9f)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + 4ed40475-c207-4ebd-bc7e-49afe8c8f0a4)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + c3ec60f2-6f1e-4301-8dca-4cf7b809395d)(label(x))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children()))))))))(Tile((id \ + 529625d9-356a-493c-a793-5fa4f7b93e41)(label(,))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 15))(sort \ + Exp))((shape(Concave 15))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + b39992d0-0283-4224-9d1a-e51bc9440f95)(content(Whitespace\" \ + \"))))(Tile((id \ + 7542242b-5136-4bc2-9b9c-30735f140547)(label(f))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + b5304c8f-34c9-4605-99be-d0507f4e6672)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 2a0d138e-74ba-4db7-9962-7ef419c56dc0)(label(b))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + e859f280-7c20-474e-9199-d461338ed7ba)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + 500daabf-5b93-41be-8d74-e888efccc3c6)(label(y))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children())))))))))))))(Secondary((id \ + f9008b43-eb37-4f20-8288-21730a00cfbc)(content(Whitespace\" \ + \"))))(Secondary((id \ + 75ceecb7-3e64-4d27-b023-695cf1c84001)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + e62cbb30-9d9b-4379-860b-7cd8ba6b7a46)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 667c7f20-f052-4b97-a3dd-b218e6e0ca36)(label(let = \ + in))(mold((out Exp)(in_(Pat Exp))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 17))(sort Exp))))))(shards(0 1 \ + 2))(children(((Secondary((id \ + 75e69bc3-13ab-47ab-a5fb-8c41efc2ab19)(content(Whitespace\" \ + \"))))(Tile((id \ + b87b594b-269c-41e6-a0d4-3ef656087765)(label(list_length))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 96cba48e-755b-48a3-9205-81c4895f9823)(content(Whitespace\" \ + \"))))(Tile((id \ + 29b7ad19-9afa-4988-a121-e849985757cc)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 1d792ce3-2829-4a10-b39c-da41929c6f8b)(content(Whitespace\" \ + \"))))(Tile((id \ + 673bb7d6-17d2-48ff-b510-7f263e931dc5)(label(forall \ + ->))(mold((out Typ)(in_(TPat))(nibs(((shape Convex)(sort \ + Typ))((shape(Concave 14))(sort Typ))))))(shards(0 \ + 1))(children(((Secondary((id \ + 990868f0-0b96-48f2-8be3-dc46a5e646ec)(content(Whitespace\" \ + \"))))(Tile((id \ + 1344c73d-4fa9-440b-99db-6ffbbf521ffe)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 8936b101-cda3-4ab5-b814-ca4cf531bc1c)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + ea04d1fc-1502-432a-9d50-5c67eda840c4)(content(Whitespace\" \ + \"))))(Tile((id 65a53d44-aa06-486a-b2c2-da74363f6569)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id \ + 7a3e47cc-1fa7-4cb8-9d21-a8e2a2056394)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 1d890687-75e1-4e6a-8667-a6698bd7cfad)(content(Whitespace\" \ + \"))))(Tile((id \ + c204f982-3974-4638-8d45-474543fe2d98)(label(->))(mold((out \ + Typ)(in_())(nibs(((shape(Concave 6))(sort \ + Typ))((shape(Concave 6))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 45eae717-5578-4faf-a4eb-88ad779586b9)(content(Whitespace\" \ + \"))))(Tile((id \ + 9dfbcc29-143e-4401-b6be-65368b51b436)(label(Int))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children())))(Secondary((id \ + b06a2789-c2aa-41ca-902f-c8461eea3fb7)(content(Whitespace\" \ + \")))))((Secondary((id \ + 148a1cb1-7874-4a6f-8f87-bee712bd36df)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + c889e055-d438-4564-b5a8-a3e12bea4882)(label(typfun \ + ->))(mold((out Exp)(in_(TPat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + ec5f5c24-9fe1-4597-8c16-47111b2d9326)(content(Whitespace\" \ + \"))))(Tile((id \ + cc54e849-a52f-4199-a7d4-9fb85a2e659d)(label(a))(mold((out \ + TPat)(in_())(nibs(((shape Convex)(sort TPat))((shape \ + Convex)(sort \ + TPat))))))(shards(0))(children())))(Secondary((id \ + 6381761f-cd9f-4d53-b9f7-33f3934836ea)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 55908c47-4807-4903-b209-7d2e1c97f444)(content(Whitespace\" \ + \"))))(Tile((id \ + eeca22d4-8f3f-417f-bb29-1fd63e213dd8)(label(fun \ + ->))(mold((out Exp)(in_(Pat))(nibs(((shape Convex)(sort \ + Exp))((shape(Concave 14))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 4e8322c3-bbe2-4e31-a317-0ac6a7f5c4eb)(content(Whitespace\" \ + \"))))(Tile((id \ + 4ca6ea59-fa8f-413d-a50c-73bd8c42ca1e)(label(l))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 7a8be493-8da0-4cb7-88c7-32fdca9fd952)(content(Whitespace\" \ + \"))))(Tile((id \ + 2b0587d4-bade-4601-a255-131007e9aa54)(label(:))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 12))(sort \ + Pat))((shape(Concave 12))(sort \ + Typ))))))(shards(0))(children())))(Secondary((id \ + 81f7e8c3-9791-4af2-a104-14c08fbc8a69)(content(Whitespace\" \ + \"))))(Tile((id cc82b421-4cdf-4cac-8e48-43e0b8e17707)(label([ \ + ]))(mold((out Typ)(in_(Typ))(nibs(((shape Convex)(sort \ + Typ))((shape Convex)(sort Typ))))))(shards(0 \ + 1))(children(((Tile((id \ + 55955b07-22bb-42ed-9303-a3fc1e391a7f)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort \ + Typ))))))(shards(0))(children()))))))))(Secondary((id \ + 2ad5c071-2227-468e-b04d-5446fbe2b615)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 022ed86b-84b9-4b3a-b141-57a61504e634)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 6fcf1112-9f01-4925-b436-b07c25b97ff2)(label(case \ + end))(mold((out Exp)(in_(Rul))(nibs(((shape Convex)(sort \ + Exp))((shape Convex)(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 01273f90-4def-4b70-a62d-b1ba96c336e9)(content(Whitespace\" \ + \"))))(Tile((id \ + fa1d5f5a-66af-4665-ad51-ac09e5f1381b)(label(l))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 0d3c9e5e-4e5c-4608-9256-59d58e9751c1)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + 386721b7-716b-460c-8627-ed4178a545fb)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 21))(sort \ + Exp))((shape(Concave 21))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 1cfb6cc3-eed6-43d6-8725-a2910ea65758)(content(Whitespace\" \ + \"))))(Tile((id \ + 5ef0f099-e7a0-4314-8270-07db3a1ccb1e)(label([]))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + cc25fa53-916a-48dd-a0bf-4568830e311a)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 6a9989f1-e856-486c-bee9-ae166a274e20)(content(Whitespace\" \ + \"))))(Tile((id \ + c738920d-a28a-4491-984f-37974eac24b5)(label(0))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + f434b12c-1dfb-4171-a491-eef97c57cb51)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ + b4fc4437-f64e-4f18-9767-e3d07eb58283)(label(| =>))(mold((out \ + Rul)(in_(Pat))(nibs(((shape(Concave 21))(sort \ + Exp))((shape(Concave 21))(sort Exp))))))(shards(0 \ + 1))(children(((Secondary((id \ + 15b71a7f-e121-4cb7-87e7-6cd34311578c)(content(Whitespace\" \ + \"))))(Tile((id \ + ef2a816b-8c42-4d03-9341-318a0849283d)(label(hd))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Tile((id \ + b3b13782-65c6-4df1-9000-dc2709d67c06)(label(::))(mold((out \ + Pat)(in_())(nibs(((shape(Concave 7))(sort \ + Pat))((shape(Concave 7))(sort \ + Pat))))))(shards(0))(children())))(Tile((id \ + 10df6bbe-686d-4739-986c-504de476497a)(label(tl))(mold((out \ + Pat)(in_())(nibs(((shape Convex)(sort Pat))((shape \ + Convex)(sort Pat))))))(shards(0))(children())))(Secondary((id \ + 560ba905-59ed-4b0f-b958-3c4b9e5813c1)(content(Whitespace\" \ + \")))))))))(Secondary((id \ + 51358db7-933c-456b-b73c-7ab0bf112d71)(content(Whitespace\" \ + \"))))(Tile((id \ + a86bedfb-70a7-4906-ba28-631c705586b2)(label(1))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Secondary((id \ + 519ad1eb-b19a-4447-a2a9-bf906527765a)(content(Whitespace\" \ + \"))))(Tile((id \ + d777f3b0-b2ea-4725-b928-a462e00d9281)(label(+))(mold((out \ + Exp)(in_())(nibs(((shape(Concave 6))(sort \ + Exp))((shape(Concave 6))(sort \ + Exp))))))(shards(0))(children())))(Secondary((id \ + 4d229f35-897c-4d30-8bdb-0425dd7031a2)(content(Whitespace\" \ + \"))))(Tile((id \ + 29f706a8-64c9-42c9-ad50-85feaf02b0eb)(label(list_length))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0))(children())))(Tile((id \ + 2d373321-8994-4495-93f1-2eb2a498df5a)(label(@< >))(mold((out \ + Exp)(in_(Typ))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + a9464742-2fa7-4b5a-8bcd-e167571c719a)(label(a))(mold((out \ + Typ)(in_())(nibs(((shape Convex)(sort Typ))((shape \ + Convex)(sort Typ))))))(shards(0))(children()))))))))(Tile((id \ + c8d0ab0a-1ac6-49c6-9e3f-1827b74cad60)(label(\"(\"\")\"))(mold((out \ + Exp)(in_(Exp))(nibs(((shape(Concave 2))(sort Exp))((shape \ + Convex)(sort Exp))))))(shards(0 1))(children(((Tile((id \ + bffbd8ae-8579-4588-9453-68634acf5441)(label(tl))(mold((out \ + Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ + Convex)(sort \ + Exp))))))(shards(0))(children()))))))))(Secondary((id \ + a4a52e3e-c4fe-4b62-a7a6-2e3ca370ccca)(content(Whitespace\" \ + \"))))(Secondary((id \ + 0bf24958-e48d-4e88-b326-1700d756dea0)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + 1d2368d0-fdce-4ebb-9fbe-514b6e74e232)(content(Whitespace\" \ + \"))))(Secondary((id \ + bacbb401-f981-45a2-a27c-b789bce6074e)(content(Whitespace\"\\226\\143\\142\")))))))))(Secondary((id \ + ae7692c4-5cb7-4ecc-afcc-c60ad2fd7cf1)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ 325d816c-fcaf-4734-a327-3c7e241b7d9c)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ 272ef5a0-043b-451d-a6e4-3f18571d2c60)(content(Comment\"# \ Strings #\"))))(Secondary((id \ @@ -10446,7 +11019,7 @@ let startup : PersistentData.t = Exp)(in_())(nibs(((shape(Concave 10))(sort \ Exp))((shape(Concave 10))(sort \ Exp))))))(shards(0))(children())))(Secondary((id \ - f59bc277-d399-48e3-8d1b-72164b9e13bb)(content(Whitespace\"\\226\\143\\142\")))))((Secondary((id \ + f59bc277-d399-48e3-8d1b-72164b9e13bb)(content(Whitespace\"\\226\\143\\142\"))))(Secondary((id \ 446ce379-8fef-47e5-85d4-f7d3fc16dd6c)(content(Whitespace\"\\226\\143\\142\"))))(Tile((id \ 31a81066-ecfa-49ce-a762-34904947da99)(label(2))(mold((out \ Exp)(in_())(nibs(((shape Convex)(sort Exp))((shape \ @@ -10524,6 +11097,22 @@ let startup : PersistentData.t = | a::b::[] => true \n\ end\n\ in\n\n\ + # Polymorphic Functions #\n\ + let poly_id : forall a -> a -> a =\n\ + typfun a -> fun x : a -> x\n\ + in\n\ + let apply_both : forall a -> forall b ->\n\ + (forall c -> c -> c) -> ((a, b) -> (a, b)) =\n\ + typfun a -> typfun b -> fun f : forall c -> (c -> c) ->\n\ + fun (x, y) : (a, b) -> (f@(x), f@(y))\n\ + in\n\ + let list_length : forall a -> [a] -> Int =\n\ + typfun a -> fun l : [a] ->\n\ + case l\n\ + | [] => 0\n\ + | hd::tl => 1 + list_length@(tl)\n\ + end\n\ + in\n\n\ # Strings #\n\ let string_lits = \"Hello, world!\" in \n\ let string_equality = string_lits $== \"Hello, world!\" in \n\n\ From a7ada80e3181eafd168d19f988628786d2a4a39e Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Tue, 26 Mar 2024 16:16:29 -0400 Subject: [PATCH 192/229] Differentiate type fun application and moving typap past cast. --- src/haz3lcore/dynamics/Stepper.re | 1 + src/haz3lcore/dynamics/Transition.re | 4 +++- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/dynamics/Stepper.re b/src/haz3lcore/dynamics/Stepper.re index 3f9f856dc4..04f1c5c4d6 100644 --- a/src/haz3lcore/dynamics/Stepper.re +++ b/src/haz3lcore/dynamics/Stepper.re @@ -415,6 +415,7 @@ let get_justification: step_kind => string = | Projection => "projection" // TODO(Matt): We don't want to show projection to the user | InvalidStep => "error" | VarLookup => "variable lookup" + | CastTypAp | CastAp | Cast => "cast calculus" | FixClosure => "fixpoint closure" diff --git a/src/haz3lcore/dynamics/Transition.re b/src/haz3lcore/dynamics/Transition.re index 572cfd3920..a5db44b365 100644 --- a/src/haz3lcore/dynamics/Transition.re +++ b/src/haz3lcore/dynamics/Transition.re @@ -56,6 +56,7 @@ type step_kind = | UpdateTest | TypFunAp | FunAp + | CastTypAp | CastAp | BuiltinWrap | BuiltinAp(string) @@ -299,7 +300,7 @@ module Transition = (EV: EV_MODE) => { Typ.subst(tau, x, t), Typ.subst(tau, x', t'), ), - kind: TypFunAp, + kind: CastTypAp, value: false, }) | _ => @@ -716,6 +717,7 @@ let should_hide_step = (~settings: CoreSettings.Evaluation.t) => | Conditional(_) | InvalidStep => false | VarLookup => !settings.show_lookup_steps + | CastTypAp | CastAp | Cast => !settings.show_casts | FixUnwrap => !settings.show_fixpoints diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index d786cc5984..2158d250ab 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -146,6 +146,7 @@ let mk = | (FunClosure, _) | (FixClosure, _) | (UpdateTest, _) + | (CastTypAp, _) | (CastAp, _) | (BuiltinWrap, _) | (BuiltinAp(_), _) From 69f2d8a033c3a81abe6f902f5fe3e114bfc9aba6 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 1 Apr 2024 14:48:42 -0400 Subject: [PATCH 193/229] Rename a variable. --- src/haz3lcore/dynamics/EvaluatorStep.re | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/EvaluatorStep.re b/src/haz3lcore/dynamics/EvaluatorStep.re index 373cd70d44..2684cbd77a 100644 --- a/src/haz3lcore/dynamics/EvaluatorStep.re +++ b/src/haz3lcore/dynamics/EvaluatorStep.re @@ -229,8 +229,8 @@ let rec compose = (ctx: EvalCtx.t, d: DHExp.t): DHExp.t => { let d2 = compose(ctx, d); Sequence(d1, d2); | TypAp(ctx, typ) => - let d2 = compose(ctx, d); - TypAp(d2, typ); + let d1 = compose(ctx, d); + TypAp(d1, typ); | Ap1(ctx, d2) => let d1 = compose(ctx, d); Ap(d1, d2); From 30d0a86870658abfc3967512f7dded94d50d1719 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Mon, 1 Apr 2024 15:01:42 -0400 Subject: [PATCH 194/229] Add TypFun case to unwrap. --- src/haz3lcore/dynamics/EvalCtx.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/dynamics/EvalCtx.re b/src/haz3lcore/dynamics/EvalCtx.re index 528eb5c66c..7f20e9ec28 100644 --- a/src/haz3lcore/dynamics/EvalCtx.re +++ b/src/haz3lcore/dynamics/EvalCtx.re @@ -175,6 +175,7 @@ let rec unwrap = (ctx: t, sel: cls): option(t) => { | (Let2, Let2(_, _, c)) | (Fun, Fun(_, _, c, _)) | (FixF, FixF(_, _, c)) + | (TypAp, TypAp(c, _)) | (Ap1, Ap1(c, _)) | (Ap2, Ap2(_, c)) | (BinBoolOp1, BinBoolOp1(_, c, _)) From c11977781970a509dab111625f1253f9083947b6 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 3 Apr 2024 22:50:51 -0400 Subject: [PATCH 195/229] Add type pretty printing and use it to augment typfun names when they are applied. --- src/haz3lcore/dynamics/DH.re | 8 ++++ src/haz3lcore/dynamics/Transition.re | 25 +++++++++-- src/haz3lcore/statics/TypBase.re | 65 ++++++++++++++++++++++++++++ src/haz3lweb/view/Type.re | 19 +------- 4 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index 42271935b6..cd137ff68a 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -62,6 +62,7 @@ module rec DHExp: { let fast_equal: (t, t) => bool; + let assign_name_if_none: (t, option(Var.t)) => t; let ty_subst: (Typ.t, TypVar.t, t) => t; } = { [@deriving (show({with_path: false}), sexp, yojson)] @@ -357,6 +358,13 @@ module rec DHExp: { && i1 == i2; }; + let assign_name_if_none = (t, name) => + switch (t) { + | Fun(arg, ty, body, None) => Fun(arg, ty, body, name) + | TypFun(utpat, body, None) => TypFun(utpat, body, name) + | _ => t + }; + let rec ty_subst = (s: Typ.t, x: TypVar.t, exp: DHExp.t): t => { let re = e2 => ty_subst(s, x, e2); let t_re = ty => Typ.subst(s, x, ty); diff --git a/src/haz3lcore/dynamics/Transition.re b/src/haz3lcore/dynamics/Transition.re index a5db44b365..3eb97031d4 100644 --- a/src/haz3lcore/dynamics/Transition.re +++ b/src/haz3lcore/dynamics/Transition.re @@ -277,19 +277,38 @@ module Transition = (EV: EV_MODE) => { let. _ = otherwise(env, d => TypAp(d, tau)) and. d' = req_value(req(state, env), d => TypAp(d, tau), d); switch (d') { - | TypFun(utpat, tfbody, _) => + | TypFun(utpat, tfbody, name) => /* Rule ITTLam */ switch (Term.UTPat.tyvar_of_utpat(utpat)) { | Some(tyvar) => /* Perform substitution */ Step({ - apply: () => DHExp.ty_subst(tau, tyvar, tfbody), + apply: () => + DHExp.assign_name_if_none( + /* Inherit name for user clarity */ + DHExp.ty_subst(tau, tyvar, tfbody), + Option.map( + x => x ++ "@<" ++ Typ.pretty_print(tau) ++ ">", + name, + ), + ), kind: TypFunAp, value: false, }) | None => /* Treat a hole or invalid tyvar name as a unique type variable that doesn't appear anywhere else. Thus instantiating it at anything doesn't produce any substitutions. */ - Step({apply: () => tfbody, kind: TypFunAp, value: false}) + Step({ + apply: () => + DHExp.assign_name_if_none( + tfbody, + Option.map( + x => x ++ "@<" ++ Typ.pretty_print(tau) ++ ">", + name, + ), + ), + kind: TypFunAp, + value: false, + }) } | Cast(d'', Forall(x, t), Forall(x', t')) => /* Rule ITTApCast */ diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 4d21e483f4..58690c3aec 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -71,6 +71,8 @@ module rec Typ: { let sum_entry: (Constructor.t, sum_map) => option(sum_entry); let get_sum_constructors: (Ctx.t, t) => option(sum_map); let is_unknown: t => bool; + let needs_parens: t => bool; + let pretty_print: t => string; } = { [@deriving (show({with_path: false}), sexp, yojson)] type type_provenance = @@ -477,6 +479,69 @@ module rec Typ: { | Unknown(_) => true | _ => false }; + + /* Does the type require parentheses when on the left of an arrow for printing? */ + let needs_parens = (ty: t): bool => + switch (ty) { + | Unknown(_) + | Int + | Float + | String + | Bool + | Var(_) => false + | Rec(_, _) + | Forall(_, _) => true + | List(_) => false /* is already wrapped in [] */ + | Arrow(_, _) => true + | Prod(_) + | Sum(_) => true /* disambiguate between (A + B) -> C and A + (B -> C) */ + }; + + /* Essentially recreates haz3lweb/view/Type.re's view_ty but with string output */ + let rec pretty_print = (ty: t): string => + switch (ty) { + | Unknown(_) => "?" + | Int => "Int" + | Float => "Float" + | Bool => "Bool" + | String => "String" + | Var(tvar) => tvar + | List(t) => "[" ++ pretty_print(t) ++ "]" + | Arrow(t1, t2) => paren_pretty_print(t1) ++ "->" ++ pretty_print(t2) + | Sum(sm) => + switch (sm) { + | [] => "+?" + | [t0] => "+" ++ ctr_pretty_print(t0) + | [t0, ...ts] => + List.fold_left( + (acc, t) => acc ++ "+" ++ ctr_pretty_print(t), + ctr_pretty_print(t0), + ts, + ) + } + | Prod([]) => "()" + | Prod([t0, ...ts]) => + "(" + ++ List.fold_left( + (acc, t) => acc ++ ", " ++ pretty_print(t), + pretty_print(t0), + ts, + ) + ++ ")" + | Rec(tv, t) => "rec " ++ tv ++ "->" ++ pretty_print(t) + | Forall(tv, t) => "forall " ++ tv ++ "->" ++ pretty_print(t) + } + and ctr_pretty_print = ((ctr, typ)) => + switch (typ) { + | None => ctr + | Some(typ) => ctr ++ "(" ++ pretty_print(typ) ++ ")" + } + and paren_pretty_print = typ => + if (needs_parens(typ)) { + "(" ++ pretty_print(typ) ++ ")"; + } else { + pretty_print(typ); + }; } and Ctx: { diff --git a/src/haz3lweb/view/Type.re b/src/haz3lweb/view/Type.re index eb0f198d38..b98ea1afd3 100644 --- a/src/haz3lweb/view/Type.re +++ b/src/haz3lweb/view/Type.re @@ -17,23 +17,6 @@ let prov_view: Typ.type_provenance => Node.t = | TypeHole => div(~attr=clss(["typ-mod", "type-hole"]), [text("𝜏")]) | SynSwitch => div(~attr=clss(["typ-mod", "syn-switch"]), [text("⇒")]); -/* Does the type require parentheses when on the left of an arrow? */ -let needs_parens = (ty: Haz3lcore.Typ.t): bool => - switch (ty) { - | Unknown(_) - | Int - | Float - | String - | Bool - | Var(_) => false - | Rec(_, _) - | Forall(_, _) => true - | List(_) => false /* is already wrapped in [] */ - | Arrow(_, _) => true - | Prod(_) - | Sum(_) => true /* disambiguate between (A + B) -> C and A + (B -> C) */ - }; - let rec view_ty = (~strip_outer_parens=false, ty: Haz3lcore.Typ.t): Node.t => switch (ty) { | Unknown(prov) => @@ -124,7 +107,7 @@ and ctr_view = ((ctr, typ)) => ] } and paren_view = typ => - if (needs_parens(typ)) { + if (Typ.needs_parens(typ)) { [text("("), view_ty(~strip_outer_parens=true, typ), text(")")]; } else { [view_ty(typ)]; From fa59fae948b1f1fa0f662f5fe5590c874f03820c Mon Sep 17 00:00:00 2001 From: Cyrus Omar Date: Thu, 11 Apr 2024 23:48:09 -0400 Subject: [PATCH 196/229] add typfun expanding form --- src/haz3lcore/assistant/AssistantForms.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/assistant/AssistantForms.re b/src/haz3lcore/assistant/AssistantForms.re index b9fb8bffa8..2080d9427f 100644 --- a/src/haz3lcore/assistant/AssistantForms.re +++ b/src/haz3lcore/assistant/AssistantForms.re @@ -25,6 +25,7 @@ module Typ = { let of_leading_delim: list((Token.t, Typ.t)) = [ ("case" ++ leading_expander, unk), ("fun" ++ leading_expander, Arrow(unk, unk)), + ("typfun" ++ leading_expander, Forall("", unk)), ("if" ++ leading_expander, unk), ("let" ++ leading_expander, unk), ("test" ++ leading_expander, Prod([])), From 53c4c10a6c5a3798df14bbf187a0bbc6212d5258 Mon Sep 17 00:00:00 2001 From: Cyrus Omar Date: Thu, 11 Apr 2024 23:48:58 -0400 Subject: [PATCH 197/229] remove dead code related to expanding forms --- src/haz3lcore/dynamics/DH.re | 8 -------- src/haz3lcore/dynamics/DHPat.re | 7 ++----- src/haz3lcore/dynamics/Elaborator.re | 1 - src/haz3lcore/dynamics/EvaluatorPost.re | 7 ------- src/haz3lcore/dynamics/FilterMatcher.re | 2 -- src/haz3lcore/dynamics/PatternMatch.re | 4 ---- src/haz3lcore/dynamics/Substitution.re | 1 - src/haz3lcore/dynamics/Transition.re | 3 +-- src/haz3lcore/dynamics/VarErrStatus.re | 3 +-- src/haz3lcore/statics/Var.re | 6 ------ src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 3 --- src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re | 3 --- src/haz3lweb/view/dhcode/layout/DHDoc_Util.re | 4 ---- src/haz3lweb/view/dhcode/layout/DHDoc_common.re | 4 ---- src/haz3lweb/view/dhcode/layout/DHDoc_common.rei | 3 --- 15 files changed, 4 insertions(+), 55 deletions(-) diff --git a/src/haz3lcore/dynamics/DH.re b/src/haz3lcore/dynamics/DH.re index cd137ff68a..676687f15d 100644 --- a/src/haz3lcore/dynamics/DH.re +++ b/src/haz3lcore/dynamics/DH.re @@ -10,7 +10,6 @@ module rec DHExp: { type t = | EmptyHole(MetaVar.t, HoleInstanceId.t) | NonEmptyHole(ErrStatus.HoleReason.t, MetaVar.t, HoleInstanceId.t, t) - | ExpandingKeyword(MetaVar.t, HoleInstanceId.t, ExpandingKeyword.t) | FreeVar(MetaVar.t, HoleInstanceId.t, Var.t) | InvalidText(MetaVar.t, HoleInstanceId.t, string) | InconsistentBranches(MetaVar.t, HoleInstanceId.t, case) @@ -70,7 +69,6 @@ module rec DHExp: { /* Hole types */ | EmptyHole(MetaVar.t, HoleInstanceId.t) | NonEmptyHole(ErrStatus.HoleReason.t, MetaVar.t, HoleInstanceId.t, t) - | ExpandingKeyword(MetaVar.t, HoleInstanceId.t, ExpandingKeyword.t) | FreeVar(MetaVar.t, HoleInstanceId.t, Var.t) | InvalidText(MetaVar.t, HoleInstanceId.t, string) | InconsistentBranches(MetaVar.t, HoleInstanceId.t, case) @@ -117,7 +115,6 @@ module rec DHExp: { switch (d) { | EmptyHole(_, _) => "EmptyHole" | NonEmptyHole(_, _, _, _) => "NonEmptyHole" - | ExpandingKeyword(_, _, _) => "ExpandingKeyword" | FreeVar(_, _, _) => "FreeVar" | InvalidText(_) => "InvalidText" | BoundVar(_) => "BoundVar" @@ -209,7 +206,6 @@ module rec DHExp: { Case(strip_casts(scrut), List.map(strip_casts_rule, rules), n), ) | EmptyHole(_) as d - | ExpandingKeyword(_) as d | FreeVar(_) as d | InvalidText(_) as d | BoundVar(_) as d @@ -324,8 +320,6 @@ module rec DHExp: { | (EmptyHole(u1, i1), EmptyHole(u2, i2)) => u1 == u2 && i1 == i2 | (NonEmptyHole(reason1, u1, i1, d1), NonEmptyHole(reason2, u2, i2, d2)) => reason1 == reason2 && u1 == u2 && i1 == i2 && fast_equal(d1, d2) - | (ExpandingKeyword(u1, i1, kw1), ExpandingKeyword(u2, i2, kw2)) => - u1 == u2 && i1 == i2 && kw1 == kw2 | (FreeVar(u1, i1, x1), FreeVar(u2, i2, x2)) => u1 == u2 && i1 == i2 && x1 == x2 | (InvalidText(u1, i1, text1), InvalidText(u2, i2, text2)) => @@ -339,7 +333,6 @@ module rec DHExp: { u1 == u2 && i1 == i2 && fast_equal_case(case1, case2) | (EmptyHole(_), _) | (NonEmptyHole(_), _) - | (ExpandingKeyword(_), _) | (FreeVar(_), _) | (InvalidText(_), _) | (Closure(_), _) @@ -408,7 +401,6 @@ module rec DHExp: { | BuiltinFun(_) | EmptyHole(_) - | ExpandingKeyword(_, _, _) | FreeVar(_, _, _) | InvalidText(_, _, _) | Constructor(_) diff --git a/src/haz3lcore/dynamics/DHPat.re b/src/haz3lcore/dynamics/DHPat.re index 4909fce337..fd7c821445 100644 --- a/src/haz3lcore/dynamics/DHPat.re +++ b/src/haz3lcore/dynamics/DHPat.re @@ -5,7 +5,6 @@ type t = | EmptyHole(MetaVar.t, MetaVarInst.t) | NonEmptyHole(ErrStatus.HoleReason.t, MetaVar.t, MetaVarInst.t, t) | Wild - | ExpandingKeyword(MetaVar.t, MetaVarInst.t, ExpandingKeyword.t) | InvalidText(MetaVar.t, MetaVarInst.t, string) | BadConstructor(MetaVar.t, MetaVarInst.t, string) | Var(Var.t) @@ -39,8 +38,7 @@ let rec binds_var = (x: Var.t, dp: t): bool => | FloatLit(_) | BoolLit(_) | StringLit(_) - | Constructor(_) - | ExpandingKeyword(_, _, _) => false + | Constructor(_) => false | Var(y) => Var.eq(x, y) | Tuple(dps) => dps |> List.exists(binds_var(x)) | Cons(dp1, dp2) => binds_var(x, dp1) || binds_var(x, dp2) @@ -61,8 +59,7 @@ let rec bound_vars = (dp: t): list(Var.t) => | FloatLit(_) | BoolLit(_) | StringLit(_) - | Constructor(_) - | ExpandingKeyword(_, _, _) => [] + | Constructor(_) => [] | Var(y) => [y] | Tuple(dps) => List.flatten(List.map(bound_vars, dps)) | Cons(dp1, dp2) => bound_vars(dp1) @ bound_vars(dp2) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index 232a5b857e..601a3322c4 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -93,7 +93,6 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) => /* Hole-like forms: Don't cast */ | InvalidText(_) | FreeVar(_) - | ExpandingKeyword(_) | EmptyHole(_) | NonEmptyHole(_) => d /* DHExp-specific forms: Don't cast */ diff --git a/src/haz3lcore/dynamics/EvaluatorPost.re b/src/haz3lcore/dynamics/EvaluatorPost.re index fd3453dac9..1d679f2138 100644 --- a/src/haz3lcore/dynamics/EvaluatorPost.re +++ b/src/haz3lcore/dynamics/EvaluatorPost.re @@ -158,7 +158,6 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => | TypFun(_) | EmptyHole(_) | NonEmptyHole(_) - | ExpandingKeyword(_) | FreeVar(_) | InvalidText(_) | InconsistentBranches(_) => raise(Exception(UnevalOutsideClosure)) @@ -222,7 +221,6 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) => |> return; | EmptyHole(_) - | ExpandingKeyword(_) | FreeVar(_) | InvalidText(_) => pp_uneval(env, d) @@ -425,10 +423,6 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) => let* i = hii_add_instance(u, env); Closure(env, NonEmptyHole(reason, u, i, d')) |> return; - | ExpandingKeyword(u, _, kw) => - let* i = hii_add_instance(u, env); - Closure(env, ExpandingKeyword(u, i, kw)) |> return; - | FreeVar(u, _, x) => let* i = hii_add_instance(u, env); Closure(env, FreeVar(u, i, x)) |> return; @@ -539,7 +533,6 @@ let rec track_children_of_hole = let hii = track_children_of_hole_rules(hii, parent, rules); hii |> HoleInstanceInfo.add_parent((u, i), parent); | EmptyHole(u, i) - | ExpandingKeyword(u, i, _) | FreeVar(u, i, _) | InvalidText(u, i, _) => hii |> HoleInstanceInfo.add_parent((u, i), parent) diff --git a/src/haz3lcore/dynamics/FilterMatcher.re b/src/haz3lcore/dynamics/FilterMatcher.re index 62991a25ae..dda068d28d 100644 --- a/src/haz3lcore/dynamics/FilterMatcher.re +++ b/src/haz3lcore/dynamics/FilterMatcher.re @@ -202,7 +202,6 @@ let rec matches_exp = | (InconsistentBranches(_), _) => false | (NonEmptyHole(_), _) => false - | (ExpandingKeyword(_), _) => false | (InvalidText(_), _) => false | (InvalidOperation(_), _) => false @@ -256,7 +255,6 @@ and matches_pat = (d: DHPat.t, f: DHPat.t): bool => { | (Cons(_), _) => false | (EmptyHole(_), _) => false | (NonEmptyHole(_), _) => false - | (ExpandingKeyword(_), _) => false | (InvalidText(_), _) => false }; } diff --git a/src/haz3lcore/dynamics/PatternMatch.re b/src/haz3lcore/dynamics/PatternMatch.re index 779f685b5e..54ee83c44e 100644 --- a/src/haz3lcore/dynamics/PatternMatch.re +++ b/src/haz3lcore/dynamics/PatternMatch.re @@ -34,7 +34,6 @@ let rec matches = (dp: DHPat.t, d: DHExp.t): match_result => | (EmptyHole(_), _) | (NonEmptyHole(_), _) => IndetMatch | (Wild, _) => Matches(Environment.empty) - | (ExpandingKeyword(_), _) => DoesNotMatch | (InvalidText(_), _) => IndetMatch | (BadConstructor(_), _) => IndetMatch | (Var(x), _) => @@ -237,7 +236,6 @@ and matches_cast_Sum = | Cast(d', Unknown(_), Sum(_) | Rec(_, Sum(_))) => matches_cast_Sum(ctr, dp, d', castmaps) | FreeVar(_) - | ExpandingKeyword(_) | InvalidText(_) | Let(_) | TypAp(_) @@ -333,7 +331,6 @@ and matches_cast_Tuple = | BoundVar(_) => DoesNotMatch | FreeVar(_) => IndetMatch | InvalidText(_) => IndetMatch - | ExpandingKeyword(_) => IndetMatch | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch | TypFun(_, _, _) => DoesNotMatch @@ -475,7 +472,6 @@ and matches_cast_Cons = | BoundVar(_) => DoesNotMatch | FreeVar(_) => IndetMatch | InvalidText(_) => IndetMatch - | ExpandingKeyword(_) => IndetMatch | Let(_, _, _) => IndetMatch | FixF(_, _, _) => DoesNotMatch | TypFun(_, _, _) => DoesNotMatch diff --git a/src/haz3lcore/dynamics/Substitution.re b/src/haz3lcore/dynamics/Substitution.re index c4c92feed1..11d949383c 100644 --- a/src/haz3lcore/dynamics/Substitution.re +++ b/src/haz3lcore/dynamics/Substitution.re @@ -9,7 +9,6 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t => } | FreeVar(_) => d2 | InvalidText(_) => d2 - | ExpandingKeyword(_) => d2 | Sequence(d3, d4) => let d3 = subst_var(d1, x, d3); let d4 = subst_var(d1, x, d4); diff --git a/src/haz3lcore/dynamics/Transition.re b/src/haz3lcore/dynamics/Transition.re index 3eb97031d4..943f781a34 100644 --- a/src/haz3lcore/dynamics/Transition.re +++ b/src/haz3lcore/dynamics/Transition.re @@ -645,8 +645,7 @@ module Transition = (EV: EV_MODE) => { | EmptyHole(_) | FreeVar(_) | InvalidText(_) - | InvalidOperation(_) - | ExpandingKeyword(_) => + | InvalidOperation(_) => let. _ = otherwise(env, d); Indet; | Cast(d, t1, t2) => diff --git a/src/haz3lcore/dynamics/VarErrStatus.re b/src/haz3lcore/dynamics/VarErrStatus.re index 8bb6c4ebc8..167db32cad 100644 --- a/src/haz3lcore/dynamics/VarErrStatus.re +++ b/src/haz3lcore/dynamics/VarErrStatus.re @@ -2,8 +2,7 @@ module HoleReason = { /* Variable: reason */ [@deriving (show({with_path: false}), sexp, yojson)] type t = - | Free - | ExpandingKeyword(ExpandingKeyword.t); + | Free; }; /* Variable: var_err */ diff --git a/src/haz3lcore/statics/Var.re b/src/haz3lcore/statics/Var.re index 998e53262b..f684dacfe5 100644 --- a/src/haz3lcore/statics/Var.re +++ b/src/haz3lcore/statics/Var.re @@ -31,12 +31,6 @@ let is_case = eq("case"); let is_wild = eq("_"); -let is_keyword = s => - switch (ExpandingKeyword.mk(s)) { - | Some(_) => true - | None => false - }; - let split = (pos, name) => { let left_var = String.sub(name, 0, pos); let right_var = String.sub(name, pos, String.length(name) - pos); diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index 2158d250ab..d51e724333 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -48,7 +48,6 @@ let rec precedence = (~show_casts: bool, d: DHExp.t) => { | BoundVar(_) | FreeVar(_) | InvalidText(_) - | ExpandingKeyword(_) | BoolLit(_) | IntLit(_) | Sequence(_) @@ -326,8 +325,6 @@ let mk = | NonEmptyHole(reason, u, i, d') => go'(d', NonEmptyHole) |> annot(DHAnnot.NonEmptyHole(reason, (u, i))) - | ExpandingKeyword(u, i, k) => - DHDoc_common.mk_ExpandingKeyword((u, i), k) | FreeVar(u, i, x) => text(x) |> annot(DHAnnot.VarHole(Free, (u, i))) | InvalidText(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i)) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re index c27aa21b07..0e2bd8e004 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Pat.re @@ -6,7 +6,6 @@ let precedence = (dp: DHPat.t) => | EmptyHole(_) | NonEmptyHole(_) | Wild - | ExpandingKeyword(_) | InvalidText(_) | BadConstructor(_) | Var(_) @@ -37,8 +36,6 @@ let rec mk = | EmptyHole(u, i) => DHDoc_common.mk_EmptyHole((u, i)) | NonEmptyHole(reason, u, i, dp) => mk'(dp) |> Doc.annot(DHAnnot.NonEmptyHole(reason, (u, i))) - | ExpandingKeyword(u, i, k) => - DHDoc_common.mk_ExpandingKeyword((u, i), k) | InvalidText(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i)) | BadConstructor(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i)) | Var(x) => Doc.text(x) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re index cf69aa856d..f127804400 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Util.re @@ -89,10 +89,6 @@ let mk_EmptyHole = (~selected=false, (u, i)) => Delim.empty_hole((u, i)) |> Doc.annot(DHAnnot.EmptyHole(selected, (u, i))); -let mk_Keyword = (u, i, k) => - Doc.text(ExpandingKeyword.to_string(k)) - |> Doc.annot(DHAnnot.VarHole(ExpandingKeyword(k), (u, i))); - let mk_IntLit = n => Doc.text(string_of_int(n)); let mk_FloatLit = (f: float) => diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re index bf7c44e72f..22f4283c89 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_common.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_common.re @@ -91,10 +91,6 @@ module Delim = { let mk_EmptyHole = (~selected=false, hc: HoleInstance.t) => Delim.empty_hole(hc) |> Doc.annot(DHAnnot.EmptyHole(selected, hc)); -let mk_ExpandingKeyword = (hc, k) => - Doc.text(ExpandingKeyword.to_string(k)) - |> Doc.annot(DHAnnot.VarHole(ExpandingKeyword(k), hc)); - let mk_InvalidText = (t, hc) => Doc.text(t) |> Doc.annot(DHAnnot.Invalid(hc)); diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei b/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei index cc784817f0..098b108b90 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_common.rei @@ -64,9 +64,6 @@ module Delim: { let mk_EmptyHole: (~selected: bool=?, HoleInstance.t) => Pretty.Doc.t(DHAnnot.t); -let mk_ExpandingKeyword: - (HoleInstance.t, ExpandingKeyword.t) => Pretty.Doc.t(DHAnnot.t); - let mk_InvalidText: (string, HoleInstance.t) => Pretty.Doc.t(DHAnnot.t); let mk_Sequence: (Pretty.Doc.t('a), Pretty.Doc.t('a)) => Pretty.Doc.t('a); From 764840cad09919a917f0076a9dfa2cdc07c1ea88 Mon Sep 17 00:00:00 2001 From: Cyrus Omar Date: Sat, 13 Apr 2024 16:18:56 -0400 Subject: [PATCH 198/229] fix failing fixpoint naming test --- src/haz3lcore/dynamics/Elaborator.re | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/dynamics/Elaborator.re b/src/haz3lcore/dynamics/Elaborator.re index b5ea10214c..e8c902f2e1 100644 --- a/src/haz3lcore/dynamics/Elaborator.re +++ b/src/haz3lcore/dynamics/Elaborator.re @@ -237,13 +237,15 @@ let rec dhexp_of_uexp = switch (Term.UPat.get_bindings(p) |> Option.get) { | [f] => /* simple recursion */ - Let(dp, FixF(f, ty, add_name(Some(f), ddef)), dbody) + Let(dp, FixF(f, ty, add_name(Some(f ++ "+"), ddef)), dbody) | fs => /* mutual recursion */ let ddef = switch (ddef) { | Tuple(a) => - DHExp.Tuple(List.map2(s => add_name(Some(s)), fs, a)) + DHExp.Tuple( + List.map2(s => add_name(Some(s ++ "+")), fs, a), + ) | _ => ddef }; let uniq_id = List.nth(def.ids, 0); From 740ce2e4604b006214043f568dacd3aced5087e4 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 10:09:01 -0400 Subject: [PATCH 199/229] Update Deco.re --- src/haz3lweb/view/Deco.re | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/haz3lweb/view/Deco.re b/src/haz3lweb/view/Deco.re index 0f577762e5..6bb251cadd 100644 --- a/src/haz3lweb/view/Deco.re +++ b/src/haz3lweb/view/Deco.re @@ -278,8 +278,16 @@ module Deco = }; // faster infomap traversal - let err_holes = (_z: Zipper.t) => - List.map(term_highlight(~clss=["err-hole"]), M.error_ids); + let err_holes = (_z: Zipper.t) => { + let is_rep = (id: Id.t) => + switch (Id.Map.find_opt(id, M.terms)) { + | None => false + | Some(term) => id == Term.rep_id(term) + }; + M.error_ids + |> List.filter(is_rep) + |> List.map(term_highlight(~clss=["err-hole"])); + }; let all = (zipper, sel_seg) => List.concat([ From e37b742ad095f7d7d2ed00fa4ffdb2ae42688aea Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 11:07:10 -0400 Subject: [PATCH 200/229] Resolve merge issue --- src/haz3lcore/statics/Info.re | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 84de41d77e..8f3d75079c 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -400,7 +400,10 @@ let rec status_exp = (ctx: Ctx.t, mode: Mode.t, self: Self.exp): status_exp => | NotInHole(_) | InHole(Common(Inconsistent(Expectation(_) | WithArrow(_)))) => None /* Type checking should fail and these errors would be nullified */ | InHole(Common(NoType(_))) - | InHole(FreeVariable(_) | InexhaustiveMatch(_)) => + | InHole( + FreeVariable(_) | InexhaustiveMatch(_) | UnusedDeferral | + BadPartialAp(_), + ) => failwith("InHole(InexhaustiveMatch(impossible_err))") }; InHole(InexhaustiveMatch(additional_err)); From a511ce98807f45d388cee059df51a47682f06f49 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 12:50:56 -0400 Subject: [PATCH 201/229] add constraint_ty --- src/haz3lcore/statics/Info.re | 19 +++++++++++++++++-- src/haz3lcore/statics/Statics.re | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 8f3d75079c..43acfb0e10 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -561,12 +561,27 @@ let derived_exp = /* Add derivable attributes for pattern terms */ let derived_pat = - (~upat: UPat.t, ~ctx, ~co_ctx, ~mode, ~ancestors, ~self, ~constraint_) + ( + ~upat: UPat.t, + ~ctx, + ~co_ctx, + ~mode, + ~ancestors, + ~self, + ~constraint_, + ~constraint_ty, + ) : pat => { let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - let constraint_ = fixed_constraint_pat(upat, ctx, mode, self, constraint_); + let constraint_mode = + switch (constraint_ty) { + | None => mode + | Some(ty) => Ana(ty) + }; + let constraint_ = + fixed_constraint_pat(upat, ctx, constraint_mode, self, constraint_); { cls, self, diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 414e583287..ee4535f717 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -419,6 +419,28 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); + // let rec get_scrut_ty = ps => { + // switch (ps) { + // | [] => scrut.ty + // | [p, ...ps] => + // let (p', _m) = + // go_pat( + // ~is_synswitch=false, + // ~co_ctx=CoCtx.empty, + // p, + // m, + // ); + // switch (Info.pat_ty(p')) { + // | Unknown(_) => get_scrut_ty(ps) + // | ty => ty + // }; + // }; + // }; + // let scrut_ty = + // switch (scrut.ty) { + // | Unknown(_) => get_scrut_ty(ps) + // | _ => scrut.ty + // }; let (ps', m) = map_m( go_pat( @@ -545,6 +567,7 @@ and upat_to_info_map = ~co_ctx, ~ancestors: Info.ancestors, ~mode: Mode.t=Mode.Syn, + ~constraint_ty: option(Typ.t)=None, {ids, term} as upat: UPat.t, m: Map.t, ) @@ -559,6 +582,7 @@ and upat_to_info_map = ~ancestors, ~self=Common(self), ~constraint_, + ~constraint_ty, ); (info, add_info(ids, InfoPat(info), m)); }; From 405bfcc24864f3c5e6713cf6db2f0450b1ce315b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 12:54:55 -0400 Subject: [PATCH 202/229] implement constraint_ty --- src/haz3lcore/statics/Statics.re | 40 ++++++++++++++------------------ 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ee4535f717..0bfac2a762 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -419,28 +419,23 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - // let rec get_scrut_ty = ps => { - // switch (ps) { - // | [] => scrut.ty - // | [p, ...ps] => - // let (p', _m) = - // go_pat( - // ~is_synswitch=false, - // ~co_ctx=CoCtx.empty, - // p, - // m, - // ); - // switch (Info.pat_ty(p')) { - // | Unknown(_) => get_scrut_ty(ps) - // | ty => ty - // }; - // }; - // }; - // let scrut_ty = - // switch (scrut.ty) { - // | Unknown(_) => get_scrut_ty(ps) - // | _ => scrut.ty - // }; + let rec get_constraint_ty = ps => { + switch (ps) { + | [] => scrut.ty + | [p, ...ps] => + let (p', _m) = + go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty, p, m); + switch (Info.pat_ty(p')) { + | Unknown(_) => get_constraint_ty(ps) + | ty => ty + }; + }; + }; + let constraint_ty = + switch (scrut.ty) { + | Unknown(_) => get_constraint_ty(ps) + | _ => scrut.ty + }; let (ps', m) = map_m( go_pat( @@ -471,6 +466,7 @@ and uexp_to_info_map = ~is_synswitch=false, ~co_ctx, ~mode=Mode.Ana(scrut.ty), + ~constraint_ty=Some(constraint_ty), p, m, ); From b3510ee982899b6d4b14f2b3ebd0cfd74ea6c09c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 15:27:42 -0400 Subject: [PATCH 203/229] add Mode.of_constraint --- src/haz3lcore/statics/Info.re | 6 +----- src/haz3lcore/statics/Mode.re | 6 ++++++ src/haz3lcore/statics/Statics.re | 21 +++++++++++++-------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 43acfb0e10..b71de65ccf 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -575,11 +575,7 @@ let derived_pat = let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - let constraint_mode = - switch (constraint_ty) { - | None => mode - | Some(ty) => Ana(ty) - }; + let constraint_mode = Mode.of_constraint(mode, constraint_ty); let constraint_ = fixed_constraint_pat(upat, ctx, constraint_mode, self, constraint_); { diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index f1e3550091..c0d2f65429 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -127,3 +127,9 @@ let of_deferred_ap_args = (length: int, ty_ins: list(Typ.t)): list(t) => ? ty_ins : List.init(length, _ => Typ.Unknown(Internal)) ) |> List.map(ty => Ana(ty)); + +let of_constraint = (mode: t, constraint_ty: option(Typ.t)): t => + switch (constraint_ty) { + | None => mode + | Some(ty) => Ana(ty) + }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0bfac2a762..c161b55086 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -485,6 +485,7 @@ and uexp_to_info_map = // Mark patterns as redundant at the top level // because redundancy doesn't make sense in a smaller context ~constraint_=p_constraint, + ~constraint_ty=Some(constraint_ty), ); ( // Override the info for the single upat @@ -679,20 +680,24 @@ and upat_to_info_map = add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => let self = Self.of_ctr(ctx, ctr); - atomic(self, Constraint.of_ctr(ctx, mode, ctr, self)); + let constraint_mode = Mode.of_constraint(mode, constraint_ty); + atomic(self, Constraint.of_ctr(ctx, constraint_mode, ctr, self)); | Ap(fn, arg) => let ctr = UPat.ctr_name(fn); let fn_mode = Mode.of_ap(ctx, mode, ctr); let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); let (ty_in, ty_out) = Typ.matched_arrow(ctx, fn.ty); let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); - add( - ~self=Just(ty_out), - ~ctx=arg.ctx, - ~constraint_= - Constraint.of_ap(ctx, mode, ctr, arg.constraint_, Some(ty_out)), - m, - ); + let constraint_mode = Mode.of_constraint(mode, constraint_ty); + let constraint_ = + Constraint.of_ap( + ctx, + constraint_mode, + ctr, + arg.constraint_, + Some(ty_out), + ); + add(~self=Just(ty_out), ~ctx=arg.ctx, ~constraint_, m); | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); From 6365947779ef339f45357d2a32923b748d0ccfdc Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 14 Apr 2024 16:04:26 -0400 Subject: [PATCH 204/229] upstream constraint_ty in Statics.re --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index c161b55086..9073342576 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -433,8 +433,8 @@ and uexp_to_info_map = }; let constraint_ty = switch (scrut.ty) { - | Unknown(_) => get_constraint_ty(ps) - | _ => scrut.ty + | Unknown(_) => Some(get_constraint_ty(ps)) + | _ => None }; let (ps', m) = map_m( @@ -466,7 +466,7 @@ and uexp_to_info_map = ~is_synswitch=false, ~co_ctx, ~mode=Mode.Ana(scrut.ty), - ~constraint_ty=Some(constraint_ty), + ~constraint_ty, p, m, ); @@ -485,7 +485,7 @@ and uexp_to_info_map = // Mark patterns as redundant at the top level // because redundancy doesn't make sense in a smaller context ~constraint_=p_constraint, - ~constraint_ty=Some(constraint_ty), + ~constraint_ty, ); ( // Override the info for the single upat From 83b425564061f176af313acf1a3850153b29ca56 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Wed, 17 Apr 2024 15:28:37 -0400 Subject: [PATCH 205/229] Improve printing. --- src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re | 1 - src/haz3lweb/view/dhcode/layout/HTypDoc.re | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re index d51e724333..7d32f88cda 100644 --- a/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re +++ b/src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re @@ -625,7 +625,6 @@ let mk = DHDoc_common.Delim.colon_Fun, space(), DHDoc_Typ.mk(~enforce_inline=true, ty), - space(), ] : [] ) diff --git a/src/haz3lweb/view/dhcode/layout/HTypDoc.re b/src/haz3lweb/view/dhcode/layout/HTypDoc.re index 2552da95e5..c1ffa32652 100644 --- a/src/haz3lweb/view/dhcode/layout/HTypDoc.re +++ b/src/haz3lweb/view/dhcode/layout/HTypDoc.re @@ -108,7 +108,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { (center, true); | Rec(name, ty) => ( hcats([ - text("Rec " ++ name ++ ".{"), + text("rec " ++ name ++ "->{"), ( (~enforce_inline) => annot(HTypAnnot.Step(0), mk(~enforce_inline, ty)) @@ -120,7 +120,7 @@ let rec mk = (~parenthesize=false, ~enforce_inline: bool, ty: Typ.t): t => { ) | Forall(name, ty) => ( hcats([ - text("Forall " ++ name ++ ".{"), + text("forall " ++ name ++ "->{"), ( (~enforce_inline) => annot(HTypAnnot.Step(0), mk(~enforce_inline, ty)) From 7b36b9d8d3d3af4dd534551ba58b5a09154da949 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sat, 20 Apr 2024 01:13:50 -0400 Subject: [PATCH 206/229] Change mode of the closing typefunap mold to be static, thus only allowing it to close. --- src/haz3lcore/lang/Form.re | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/haz3lcore/lang/Form.re b/src/haz3lcore/lang/Form.re index 65a8dcd292..b400c97ed0 100644 --- a/src/haz3lcore/lang/Form.re +++ b/src/haz3lcore/lang/Form.re @@ -302,7 +302,10 @@ let forms: list((string, t)) = [ ("ap_exp", mk(ii, ["(", ")"], mk_post(P.ap, Exp, [Exp]))), ("ap_pat", mk(ii, ["(", ")"], mk_post(P.ap, Pat, [Pat]))), ("ap_typ", mk(ii, ["(", ")"], mk_post(P.ap, Typ, [Typ]))), - ("ap_exp_typ", mk(ii, ["@<", ">"], mk_post(P.ap, Exp, [Typ]))), + ( + "ap_exp_typ", + mk((Instant, Static), ["@<", ">"], mk_post(P.ap, Exp, [Typ])), + ), ("at_sign", mk_nul_infix("@", P.eqs)), // HACK: SUBSTRING REQ ("case", mk(ds, ["case", "end"], mk_op(Exp, [Rul]))), ("test", mk(ds, ["test", "end"], mk_op(Exp, [Exp]))), From 2bc7dd022798e6071192873f63a579035de79799 Mon Sep 17 00:00:00 2001 From: Crazycolorz5 Date: Sun, 28 Apr 2024 19:41:51 -0400 Subject: [PATCH 207/229] Make forall types be considered for recursion. --- src/haz3lcore/statics/Statics.re | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 7e7bb1952c..08518137e2 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -64,21 +64,23 @@ let map_m = (f, xs, m: Map.t) => let add_info = (ids: list(Id.t), info: Info.t, m: Map.t): Map.t => ids |> List.fold_left((m, id) => Id.Map.add(id, info, m), m); +let rec is_arrow_like = (t: Typ.t) => { + switch (t) { + | Unknown(_) => true + | Arrow(_) => true + | Forall(_, t) => is_arrow_like(t) + | _ => false + }; +}; + let is_recursive = (ctx, p, def, syn: Typ.t) => { switch (Term.UPat.get_num_of_vars(p), Term.UExp.get_num_of_functions(def)) { | (Some(num_vars), Some(num_fns)) when num_vars != 0 && num_vars == num_fns => switch (Typ.normalize(ctx, syn)) { - | Unknown(_) - | Arrow(_) => num_vars == 1 | Prod(syns) when List.length(syns) == num_vars => - syns - |> List.for_all( - fun - | Typ.Unknown(_) - | Arrow(_) => true - | _ => false, - ) + syns |> List.for_all(is_arrow_like) + | t when is_arrow_like(t) => num_vars == 1 | _ => false } | _ => false From 9249bfee86c36c0a0194fca6846f8775ec0f458b Mon Sep 17 00:00:00 2001 From: Matt Keenan Date: Wed, 1 May 2024 15:49:38 -0400 Subject: [PATCH 208/229] Fix #1298 --- src/haz3lcore/statics/Statics.re | 1 + 1 file changed, 1 insertion(+) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 08518137e2..29f4c27ce9 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -239,6 +239,7 @@ and uexp_to_info_map = m, ); | ListConcat(e1, e2) => + let mode = Mode.of_list_concat(ctx, mode); let ids = List.map(Term.UExp.rep_id, [e1, e2]); let (e1, m) = go(~mode, e1, m); let (e2, m) = go(~mode, e2, m); From a9e1f20b4691bcad9ca601a791dde8618f8bbf9b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 13:26:12 -0400 Subject: [PATCH 209/229] upstreamed --- src/haz3lweb/ScratchSlide.re | 4 +++- src/haz3lweb/view/Deco.re | 12 ++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/haz3lweb/ScratchSlide.re b/src/haz3lweb/ScratchSlide.re index 09860711ed..6d6214921d 100644 --- a/src/haz3lweb/ScratchSlide.re +++ b/src/haz3lweb/ScratchSlide.re @@ -51,6 +51,8 @@ let mk_statics = let term = MakeTerm.from_zip_for_sem(editor.state.zipper) |> fst; let info_map = Interface.Statics.mk_map_ctx(settings.core, ctx_init, term); let error_ids = - Statics.Map.error_ids(editor.state.meta.term_ranges, info_map); + info_map + |> Id.Map.filter((id, info) => id == Info.id_of(info)) + |> Statics.Map.error_ids(editor.state.meta.term_ranges); {term, info_map, error_ids}; }; diff --git a/src/haz3lweb/view/Deco.re b/src/haz3lweb/view/Deco.re index 6bb251cadd..0f577762e5 100644 --- a/src/haz3lweb/view/Deco.re +++ b/src/haz3lweb/view/Deco.re @@ -278,16 +278,8 @@ module Deco = }; // faster infomap traversal - let err_holes = (_z: Zipper.t) => { - let is_rep = (id: Id.t) => - switch (Id.Map.find_opt(id, M.terms)) { - | None => false - | Some(term) => id == Term.rep_id(term) - }; - M.error_ids - |> List.filter(is_rep) - |> List.map(term_highlight(~clss=["err-hole"])); - }; + let err_holes = (_z: Zipper.t) => + List.map(term_highlight(~clss=["err-hole"]), M.error_ids); let all = (zipper, sel_seg) => List.concat([ From f1ce59dae9014f50d95230b90ed770c7b08c97a7 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 13:36:19 -0400 Subject: [PATCH 210/229] Revert "upstream constraint_ty in Statics.re" This reverts commit 6365947779ef339f45357d2a32923b748d0ccfdc. --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 9073342576..c161b55086 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -433,8 +433,8 @@ and uexp_to_info_map = }; let constraint_ty = switch (scrut.ty) { - | Unknown(_) => Some(get_constraint_ty(ps)) - | _ => None + | Unknown(_) => get_constraint_ty(ps) + | _ => scrut.ty }; let (ps', m) = map_m( @@ -466,7 +466,7 @@ and uexp_to_info_map = ~is_synswitch=false, ~co_ctx, ~mode=Mode.Ana(scrut.ty), - ~constraint_ty, + ~constraint_ty=Some(constraint_ty), p, m, ); @@ -485,7 +485,7 @@ and uexp_to_info_map = // Mark patterns as redundant at the top level // because redundancy doesn't make sense in a smaller context ~constraint_=p_constraint, - ~constraint_ty, + ~constraint_ty=Some(constraint_ty), ); ( // Override the info for the single upat From 1ba9e2e845eec81083d591764cb9570fc1b0598c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 13:36:23 -0400 Subject: [PATCH 211/229] Revert "add Mode.of_constraint" This reverts commit b3510ee982899b6d4b14f2b3ebd0cfd74ea6c09c. --- src/haz3lcore/statics/Info.re | 6 +++++- src/haz3lcore/statics/Mode.re | 6 ------ src/haz3lcore/statics/Statics.re | 21 ++++++++------------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index b71de65ccf..43acfb0e10 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -575,7 +575,11 @@ let derived_pat = let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - let constraint_mode = Mode.of_constraint(mode, constraint_ty); + let constraint_mode = + switch (constraint_ty) { + | None => mode + | Some(ty) => Ana(ty) + }; let constraint_ = fixed_constraint_pat(upat, ctx, constraint_mode, self, constraint_); { diff --git a/src/haz3lcore/statics/Mode.re b/src/haz3lcore/statics/Mode.re index c0d2f65429..f1e3550091 100644 --- a/src/haz3lcore/statics/Mode.re +++ b/src/haz3lcore/statics/Mode.re @@ -127,9 +127,3 @@ let of_deferred_ap_args = (length: int, ty_ins: list(Typ.t)): list(t) => ? ty_ins : List.init(length, _ => Typ.Unknown(Internal)) ) |> List.map(ty => Ana(ty)); - -let of_constraint = (mode: t, constraint_ty: option(Typ.t)): t => - switch (constraint_ty) { - | None => mode - | Some(ty) => Ana(ty) - }; diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index c161b55086..0bfac2a762 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -485,7 +485,6 @@ and uexp_to_info_map = // Mark patterns as redundant at the top level // because redundancy doesn't make sense in a smaller context ~constraint_=p_constraint, - ~constraint_ty=Some(constraint_ty), ); ( // Override the info for the single upat @@ -680,24 +679,20 @@ and upat_to_info_map = add(~self=Just(p.ty), ~ctx=p.ctx, ~constraint_=p.constraint_, m); | Constructor(ctr) => let self = Self.of_ctr(ctx, ctr); - let constraint_mode = Mode.of_constraint(mode, constraint_ty); - atomic(self, Constraint.of_ctr(ctx, constraint_mode, ctr, self)); + atomic(self, Constraint.of_ctr(ctx, mode, ctr, self)); | Ap(fn, arg) => let ctr = UPat.ctr_name(fn); let fn_mode = Mode.of_ap(ctx, mode, ctr); let (fn, m) = go(~ctx, ~mode=fn_mode, fn, m); let (ty_in, ty_out) = Typ.matched_arrow(ctx, fn.ty); let (arg, m) = go(~ctx, ~mode=Ana(ty_in), arg, m); - let constraint_mode = Mode.of_constraint(mode, constraint_ty); - let constraint_ = - Constraint.of_ap( - ctx, - constraint_mode, - ctr, - arg.constraint_, - Some(ty_out), - ); - add(~self=Just(ty_out), ~ctx=arg.ctx, ~constraint_, m); + add( + ~self=Just(ty_out), + ~ctx=arg.ctx, + ~constraint_= + Constraint.of_ap(ctx, mode, ctr, arg.constraint_, Some(ty_out)), + m, + ); | TypeAnn(p, ann) => let (ann, m) = utyp_to_info_map(~ctx, ~ancestors, ann, m); let (p, m) = go(~ctx, ~mode=Ana(ann.ty), p, m); From fd86321a50e12449039b2489ac9698e38573265e Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 13:36:26 -0400 Subject: [PATCH 212/229] Revert "implement constraint_ty" This reverts commit 405bfcc24864f3c5e6713cf6db2f0450b1ce315b. --- src/haz3lcore/statics/Statics.re | 40 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0bfac2a762..ee4535f717 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -419,23 +419,28 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - let rec get_constraint_ty = ps => { - switch (ps) { - | [] => scrut.ty - | [p, ...ps] => - let (p', _m) = - go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty, p, m); - switch (Info.pat_ty(p')) { - | Unknown(_) => get_constraint_ty(ps) - | ty => ty - }; - }; - }; - let constraint_ty = - switch (scrut.ty) { - | Unknown(_) => get_constraint_ty(ps) - | _ => scrut.ty - }; + // let rec get_scrut_ty = ps => { + // switch (ps) { + // | [] => scrut.ty + // | [p, ...ps] => + // let (p', _m) = + // go_pat( + // ~is_synswitch=false, + // ~co_ctx=CoCtx.empty, + // p, + // m, + // ); + // switch (Info.pat_ty(p')) { + // | Unknown(_) => get_scrut_ty(ps) + // | ty => ty + // }; + // }; + // }; + // let scrut_ty = + // switch (scrut.ty) { + // | Unknown(_) => get_scrut_ty(ps) + // | _ => scrut.ty + // }; let (ps', m) = map_m( go_pat( @@ -466,7 +471,6 @@ and uexp_to_info_map = ~is_synswitch=false, ~co_ctx, ~mode=Mode.Ana(scrut.ty), - ~constraint_ty=Some(constraint_ty), p, m, ); From 17f55a4dc706ed06e51b351568055bcd25b08475 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 13:36:30 -0400 Subject: [PATCH 213/229] Revert "add constraint_ty" This reverts commit a511ce98807f45d388cee059df51a47682f06f49. --- src/haz3lcore/statics/Info.re | 19 ++----------------- src/haz3lcore/statics/Statics.re | 24 ------------------------ 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/haz3lcore/statics/Info.re b/src/haz3lcore/statics/Info.re index 43acfb0e10..8f3d75079c 100644 --- a/src/haz3lcore/statics/Info.re +++ b/src/haz3lcore/statics/Info.re @@ -561,27 +561,12 @@ let derived_exp = /* Add derivable attributes for pattern terms */ let derived_pat = - ( - ~upat: UPat.t, - ~ctx, - ~co_ctx, - ~mode, - ~ancestors, - ~self, - ~constraint_, - ~constraint_ty, - ) + (~upat: UPat.t, ~ctx, ~co_ctx, ~mode, ~ancestors, ~self, ~constraint_) : pat => { let cls = Cls.Pat(UPat.cls_of_term(upat.term)); let status = status_pat(ctx, mode, self); let ty = fixed_typ_pat(ctx, mode, self); - let constraint_mode = - switch (constraint_ty) { - | None => mode - | Some(ty) => Ana(ty) - }; - let constraint_ = - fixed_constraint_pat(upat, ctx, constraint_mode, self, constraint_); + let constraint_ = fixed_constraint_pat(upat, ctx, mode, self, constraint_); { cls, self, diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index ee4535f717..414e583287 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -419,28 +419,6 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); - // let rec get_scrut_ty = ps => { - // switch (ps) { - // | [] => scrut.ty - // | [p, ...ps] => - // let (p', _m) = - // go_pat( - // ~is_synswitch=false, - // ~co_ctx=CoCtx.empty, - // p, - // m, - // ); - // switch (Info.pat_ty(p')) { - // | Unknown(_) => get_scrut_ty(ps) - // | ty => ty - // }; - // }; - // }; - // let scrut_ty = - // switch (scrut.ty) { - // | Unknown(_) => get_scrut_ty(ps) - // | _ => scrut.ty - // }; let (ps', m) = map_m( go_pat( @@ -567,7 +545,6 @@ and upat_to_info_map = ~co_ctx, ~ancestors: Info.ancestors, ~mode: Mode.t=Mode.Syn, - ~constraint_ty: option(Typ.t)=None, {ids, term} as upat: UPat.t, m: Map.t, ) @@ -582,7 +559,6 @@ and upat_to_info_map = ~ancestors, ~self=Common(self), ~constraint_, - ~constraint_ty, ); (info, add_info(ids, InfoPat(info), m)); }; From b17a16523a5e25d2175078c860ae723d4d60706a Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 14:52:54 -0400 Subject: [PATCH 214/229] scrut.ty => scrut_ty --- src/haz3lcore/statics/Statics.re | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 414e583287..0a3ecb3f81 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -419,12 +419,28 @@ and uexp_to_info_map = let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); + // switch (scrut.ty) { + // | Unknown(_) => + // let (ps', _m) = + // map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m); + // print_endline( + // Typ.join_all( + // ~empty=Unknown(Internal), + // ctx, + // List.map(Info.pat_ty, ps'), + // ) + // == None + // ? "some" : "none", + // ); + // | _ => () + // }; + // switch () let (ps', m) = map_m( go_pat( ~is_synswitch=false, ~co_ctx=CoCtx.empty, - ~mode=Mode.Ana(scrut.ty), + ~mode=Mode.Ana(scrut_ty), ), ps, m, @@ -448,7 +464,7 @@ and uexp_to_info_map = go_pat( ~is_synswitch=false, ~co_ctx, - ~mode=Mode.Ana(scrut.ty), + ~mode=Mode.Ana(scrut_ty), p, m, ); From 368785c9ae83715ce15ffea9978472da0b9d334d Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 15:09:47 -0400 Subject: [PATCH 215/229] changed rules_to_info_map signature --- src/haz3lcore/statics/Statics.re | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0a3ecb3f81..2ba107adfd 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -416,9 +416,9 @@ and uexp_to_info_map = ); | Match(scrut, rules) => let (scrut, m) = go(~mode=Syn, scrut, m); - let rules_to_info_map = (rules: list((UPat.t, UExp.t)), m) => { - let (ps, es) = List.split(rules); - let branch_ids = List.map(UExp.rep_id, es); + let (ps, es) = List.split(rules); + let branch_ids = List.map(UExp.rep_id, es); + let rules_to_info_map = (ps: list(UPat.t), es: list(UExp.t), m) => { // switch (scrut.ty) { // | Unknown(_) => // let (ps', _m) = @@ -494,10 +494,9 @@ and uexp_to_info_map = (m, Constraint.Falsity), List.combine(ps, e_co_ctxs), ); - (es, e_co_ctxs, branch_ids, final_constraint, m); + (es, e_co_ctxs, final_constraint, m); }; - let (es, e_co_ctxs, branch_ids, final_constraint, m) = - rules_to_info_map(rules, m); + let (es, e_co_ctxs, final_constraint, m) = rules_to_info_map(ps, es, m); let e_tys = List.map(Info.exp_ty, es); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); From 14af4794819e9501552e571b575643bf4ac764f8 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 15:10:04 -0400 Subject: [PATCH 216/229] moved join check draft outside --- src/haz3lcore/statics/Statics.re | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 2ba107adfd..6ef69e8d9e 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -418,23 +418,23 @@ and uexp_to_info_map = let (scrut, m) = go(~mode=Syn, scrut, m); let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); + // switch (scrut.ty) { + // | Unknown(_) => + // let (ps', _m) = + // map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m); + // print_endline( + // Typ.join_all( + // ~empty=Unknown(Internal), + // ctx, + // List.map(Info.pat_ty, ps'), + // ) + // == None + // ? "some" : "none", + // ); + // | _ => () + // }; + // switch () let rules_to_info_map = (ps: list(UPat.t), es: list(UExp.t), m) => { - // switch (scrut.ty) { - // | Unknown(_) => - // let (ps', _m) = - // map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m); - // print_endline( - // Typ.join_all( - // ~empty=Unknown(Internal), - // ctx, - // List.map(Info.pat_ty, ps'), - // ) - // == None - // ? "some" : "none", - // ); - // | _ => () - // }; - // switch () let (ps', m) = map_m( go_pat( From cfad199f495efc491884e6abf6e1e469c312df87 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 15:16:40 -0400 Subject: [PATCH 217/229] created branch for join check --- src/haz3lcore/statics/Statics.re | 140 ++++++++++++++++--------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6ef69e8d9e..6322da5dac 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -434,75 +434,83 @@ and uexp_to_info_map = // | _ => () // }; // switch () - let rules_to_info_map = (ps: list(UPat.t), es: list(UExp.t), m) => { - let (ps', m) = - map_m( - go_pat( - ~is_synswitch=false, - ~co_ctx=CoCtx.empty, - ~mode=Mode.Ana(scrut_ty), - ), - ps, - m, - ); - let p_ctxs = List.map(Info.pat_ctx, ps'); - let (es, m) = - List.fold_left2( - ((es, m), e, ctx) => - go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), - ([], m), - es, - p_ctxs, - ); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - /* Add co-ctxs to patterns */ - let (m, final_constraint) = - List.fold_left( - ((m, acc_constraint), (p, co_ctx)) => { - let (p, m) = + let scrut_ty = Some(scrut.ty); + let (self, e_co_ctxs, m) = + switch (scrut_ty) { + | Some(scrut_ty) => + let rules_to_info_map = (ps: list(UPat.t), es: list(UExp.t), m) => { + let (ps', m) = + map_m( go_pat( ~is_synswitch=false, - ~co_ctx, + ~co_ctx=CoCtx.empty, ~mode=Mode.Ana(scrut_ty), - p, - m, - ); - let p_constraint = Info.pat_constraint(p); - if (!Incon.is_redundant(p_constraint, acc_constraint)) { - (m, Constraint.Or(p_constraint, acc_constraint)); - } else { - let info = - Info.derived_pat( - ~upat=p.term, - ~ctx=p.ctx, - ~co_ctx=p.co_ctx, - ~mode=p.mode, - ~ancestors=p.ancestors, - ~self=Redundant(p.self), - // Mark patterns as redundant at the top level - // because redundancy doesn't make sense in a smaller context - ~constraint_=p_constraint, - ); - ( - // Override the info for the single upat - add_info(p.term.ids, InfoPat(info), m), - acc_constraint // Redundant patterns are ignored - ); - }; - }, - (m, Constraint.Falsity), - List.combine(ps, e_co_ctxs), - ); - (es, e_co_ctxs, final_constraint, m); - }; - let (es, e_co_ctxs, final_constraint, m) = rules_to_info_map(ps, es, m); - let e_tys = List.map(Info.exp_ty, es); - let unwrapped_self: Self.exp = - Common(Self.match(ctx, e_tys, branch_ids)); - let is_exhaustive = Incon.is_exhaustive(final_constraint); - let self = - is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + ), + ps, + m, + ); + let p_ctxs = List.map(Info.pat_ctx, ps'); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, + ); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + /* Add co-ctxs to patterns */ + let (m, final_constraint) = + List.fold_left( + ((m, acc_constraint), (p, co_ctx)) => { + let (p, m) = + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(scrut_ty), + p, + m, + ); + let p_constraint = Info.pat_constraint(p); + if (!Incon.is_redundant(p_constraint, acc_constraint)) { + (m, Constraint.Or(p_constraint, acc_constraint)); + } else { + let info = + Info.derived_pat( + ~upat=p.term, + ~ctx=p.ctx, + ~co_ctx=p.co_ctx, + ~mode=p.mode, + ~ancestors=p.ancestors, + ~self=Redundant(p.self), + // Mark patterns as redundant at the top level + // because redundancy doesn't make sense in a smaller context + ~constraint_=p_constraint, + ); + ( + // Override the info for the single upat + add_info(p.term.ids, InfoPat(info), m), + acc_constraint // Redundant patterns are ignored + ); + }; + }, + (m, Constraint.Falsity), + List.combine(ps, e_co_ctxs), + ); + (es, e_co_ctxs, final_constraint, m); + }; + let (es, e_co_ctxs, final_constraint, m) = + rules_to_info_map(ps, es, m); + let e_tys = List.map(Info.exp_ty, es); + let unwrapped_self: Self.exp = + Common(Self.match(ctx, e_tys, branch_ids)); + let is_exhaustive = Incon.is_exhaustive(final_constraint); + let self = + is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); + (self, e_co_ctxs, m); + | None => failwith("unimplemented") + }; add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => let m = utpat_to_info_map(~ctx, ~ancestors, typat, m) |> snd; From a389e836fd9a028406cb1d61842a232360244f1c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 15:30:47 -0400 Subject: [PATCH 218/229] none branch for join check --- src/haz3lcore/statics/Statics.re | 43 +++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6322da5dac..6e3fb58f2a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -438,7 +438,8 @@ and uexp_to_info_map = let (self, e_co_ctxs, m) = switch (scrut_ty) { | Some(scrut_ty) => - let rules_to_info_map = (ps: list(UPat.t), es: list(UExp.t), m) => { + let rules_to_info_map = + (ps: list(UPat.t), es: list(UExp.t), scrut_ty: Typ.t, m) => { let (ps', m) = map_m( go_pat( @@ -501,7 +502,7 @@ and uexp_to_info_map = (es, e_co_ctxs, final_constraint, m); }; let (es, e_co_ctxs, final_constraint, m) = - rules_to_info_map(ps, es, m); + rules_to_info_map(ps, es, scrut_ty, m); let e_tys = List.map(Info.exp_ty, es); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); @@ -509,7 +510,43 @@ and uexp_to_info_map = let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); (self, e_co_ctxs, m); - | None => failwith("unimplemented") + | None => + let (ps', _) = + map_m( + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Mode.Ana(scrut.ty), + ), + ps, + m, + ); + let p_ctxs = List.map(Info.pat_ctx, ps'); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, + ); + let e_tys = List.map(Info.exp_ty, es); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + /* Add co-ctxs to patterns */ + let (_, m) = + map_m( + ((p, co_ctx)) => + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(scrut.ty), + p, + ), + List.combine(ps, e_co_ctxs), + m, + ); + (Common(Self.match(ctx, e_tys, branch_ids)), e_co_ctxs, m); }; add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From 64075dba90233cc9390ff16d81da166f86056ade Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sat, 4 May 2024 16:04:06 -0400 Subject: [PATCH 219/229] factor out code --- src/haz3lcore/statics/Statics.re | 74 +++++++++++--------------------- 1 file changed, 25 insertions(+), 49 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 6e3fb58f2a..d2a249d836 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -418,6 +418,28 @@ and uexp_to_info_map = let (scrut, m) = go(~mode=Syn, scrut, m); let (ps, es) = List.split(rules); let branch_ids = List.map(UExp.rep_id, es); + let (ps', _) = + map_m( + go_pat( + ~is_synswitch=false, + ~co_ctx=CoCtx.empty, + ~mode=Mode.Ana(scrut.ty), + ), + ps, + m, + ); + let p_ctxs = List.map(Info.pat_ctx, ps'); + let (es, m) = + List.fold_left2( + ((es, m), e, ctx) => + go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), + ([], m), + es, + p_ctxs, + ); + let e_tys = List.map(Info.exp_ty, es); + let e_co_ctxs = + List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); // switch (scrut.ty) { // | Unknown(_) => // let (ps', _m) = @@ -438,29 +460,7 @@ and uexp_to_info_map = let (self, e_co_ctxs, m) = switch (scrut_ty) { | Some(scrut_ty) => - let rules_to_info_map = - (ps: list(UPat.t), es: list(UExp.t), scrut_ty: Typ.t, m) => { - let (ps', m) = - map_m( - go_pat( - ~is_synswitch=false, - ~co_ctx=CoCtx.empty, - ~mode=Mode.Ana(scrut_ty), - ), - ps, - m, - ); - let p_ctxs = List.map(Info.pat_ctx, ps'); - let (es, m) = - List.fold_left2( - ((es, m), e, ctx) => - go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), - ([], m), - es, - p_ctxs, - ); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + let rules_to_info_map = (ps: list(UPat.t), scrut_ty: Typ.t, m) => { /* Add co-ctxs to patterns */ let (m, final_constraint) = List.fold_left( @@ -499,11 +499,9 @@ and uexp_to_info_map = (m, Constraint.Falsity), List.combine(ps, e_co_ctxs), ); - (es, e_co_ctxs, final_constraint, m); + (final_constraint, m); }; - let (es, e_co_ctxs, final_constraint, m) = - rules_to_info_map(ps, es, scrut_ty, m); - let e_tys = List.map(Info.exp_ty, es); + let (final_constraint, m) = rules_to_info_map(ps, scrut_ty, m); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); let is_exhaustive = Incon.is_exhaustive(final_constraint); @@ -511,28 +509,6 @@ and uexp_to_info_map = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); (self, e_co_ctxs, m); | None => - let (ps', _) = - map_m( - go_pat( - ~is_synswitch=false, - ~co_ctx=CoCtx.empty, - ~mode=Mode.Ana(scrut.ty), - ), - ps, - m, - ); - let p_ctxs = List.map(Info.pat_ctx, ps'); - let (es, m) = - List.fold_left2( - ((es, m), e, ctx) => - go'(~ctx, ~mode, e, m) |> (((e, m)) => (es @ [e], m)), - ([], m), - es, - p_ctxs, - ); - let e_tys = List.map(Info.exp_ty, es); - let e_co_ctxs = - List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); /* Add co-ctxs to patterns */ let (_, m) = map_m( From d736500e50c4cef06570eed03f76e230d678f1be Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 14:28:23 -0400 Subject: [PATCH 220/229] code simplification --- src/haz3lcore/statics/Statics.re | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index d2a249d836..0ac6f0553a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -457,7 +457,7 @@ and uexp_to_info_map = // }; // switch () let scrut_ty = Some(scrut.ty); - let (self, e_co_ctxs, m) = + let (self, m) = switch (scrut_ty) { | Some(scrut_ty) => let rules_to_info_map = (ps: list(UPat.t), scrut_ty: Typ.t, m) => { @@ -507,7 +507,7 @@ and uexp_to_info_map = let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); - (self, e_co_ctxs, m); + (self, m); | None => /* Add co-ctxs to patterns */ let (_, m) = @@ -522,7 +522,7 @@ and uexp_to_info_map = List.combine(ps, e_co_ctxs), m, ); - (Common(Self.match(ctx, e_tys, branch_ids)), e_co_ctxs, m); + (Common(Self.match(ctx, e_tys, branch_ids)), m); }; add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From 804f5e289c191b224caa276f24c00f2a5e2a6a3c Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 14:38:25 -0400 Subject: [PATCH 221/229] rules_to_info_map => pats_to_info_map --- src/haz3lcore/statics/Statics.re | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 0ac6f0553a..8efa67851a 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -460,7 +460,7 @@ and uexp_to_info_map = let (self, m) = switch (scrut_ty) { | Some(scrut_ty) => - let rules_to_info_map = (ps: list(UPat.t), scrut_ty: Typ.t, m) => { + let pats_to_info_map = (ps: list(UPat.t), m) => { /* Add co-ctxs to patterns */ let (m, final_constraint) = List.fold_left( @@ -469,7 +469,7 @@ and uexp_to_info_map = go_pat( ~is_synswitch=false, ~co_ctx, - ~mode=Mode.Ana(scrut_ty), + ~mode=Mode.Ana(scrut.ty), p, m, ); @@ -501,7 +501,7 @@ and uexp_to_info_map = ); (final_constraint, m); }; - let (final_constraint, m) = rules_to_info_map(ps, scrut_ty, m); + let (final_constraint, m) = pats_to_info_map(ps, m); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); let is_exhaustive = Incon.is_exhaustive(final_constraint); From 81fa2865f55de2b3b9dfafda0d7337e7b126784b Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 15:28:30 -0400 Subject: [PATCH 222/229] some branch for join check --- src/haz3lcore/statics/Statics.re | 52 +++++++++++++++++++------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 8efa67851a..76f8d4f5fb 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -465,6 +465,16 @@ and uexp_to_info_map = let (m, final_constraint) = List.fold_left( ((m, acc_constraint), (p, co_ctx)) => { + let p_constraint = + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(scrut_ty), + p, + m, + ) + |> fst + |> Info.pat_constraint; let (p, m) = go_pat( ~is_synswitch=false, @@ -473,28 +483,28 @@ and uexp_to_info_map = p, m, ); - let p_constraint = Info.pat_constraint(p); - if (!Incon.is_redundant(p_constraint, acc_constraint)) { - (m, Constraint.Or(p_constraint, acc_constraint)); - } else { - let info = - Info.derived_pat( - ~upat=p.term, - ~ctx=p.ctx, - ~co_ctx=p.co_ctx, - ~mode=p.mode, - ~ancestors=p.ancestors, - ~self=Redundant(p.self), - // Mark patterns as redundant at the top level - // because redundancy doesn't make sense in a smaller context - ~constraint_=p_constraint, - ); - ( - // Override the info for the single upat - add_info(p.term.ids, InfoPat(info), m), - acc_constraint // Redundant patterns are ignored + let is_redundant = + Incon.is_redundant(p_constraint, acc_constraint); + let self = is_redundant ? Self.Redundant(p.self) : p.self; + let info = + Info.derived_pat( + ~upat=p.term, + ~ctx=p.ctx, + ~co_ctx=p.co_ctx, + ~mode=p.mode, + ~ancestors=p.ancestors, + ~self, + // Mark patterns as redundant at the top level + // because redundancy doesn't make sense in a smaller context + ~constraint_=p_constraint, ); - }; + ( + // Override the info for the single upat + add_info(p.term.ids, InfoPat(info), m), + is_redundant + ? acc_constraint // Redundant patterns are ignored + : Constraint.Or(p_constraint, acc_constraint), + ); }, (m, Constraint.Falsity), List.combine(ps, e_co_ctxs), From 3efe0611ddd40ba6ff0d3427ddf4e41e14eda7c1 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 15:37:17 -0400 Subject: [PATCH 223/229] unknown scrutinee type handling mostly done --- src/haz3lcore/statics/Statics.re | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 76f8d4f5fb..f52617a7bc 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -440,7 +440,6 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - // switch (scrut.ty) { // | Unknown(_) => // let (ps', _m) = // map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m); @@ -456,7 +455,11 @@ and uexp_to_info_map = // | _ => () // }; // switch () - let scrut_ty = Some(scrut.ty); + let scrut_ty = + switch (scrut.ty) { + | Unknown(_) => None + | ty => Some(ty) + }; let (self, m) = switch (scrut_ty) { | Some(scrut_ty) => From 9f7087b1e0d7ac430e2c65317e8d3041992b66ff Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 15:48:38 -0400 Subject: [PATCH 224/229] unknown scrutinee type handling done --- src/haz3lcore/statics/Statics.re | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index f52617a7bc..857ba17b9b 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -440,24 +440,13 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - // | Unknown(_) => - // let (ps', _m) = - // map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m); - // print_endline( - // Typ.join_all( - // ~empty=Unknown(Internal), - // ctx, - // List.map(Info.pat_ty, ps'), - // ) - // == None - // ? "some" : "none", - // ); - // | _ => () - // }; - // switch () let scrut_ty = switch (scrut.ty) { - | Unknown(_) => None + | Unknown(_) => + map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m) + |> fst + |> List.map(Info.pat_ty) + |> Typ.join_all(~empty=Unknown(Internal), ctx) | ty => Some(ty) }; let (self, m) = From 9a021ce9da81699b5503bf11aba39f2929ed9d0f Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 15:56:20 -0400 Subject: [PATCH 225/229] scrut_ty => constraint_ty --- src/haz3lcore/statics/Statics.re | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 857ba17b9b..fcee5a4b0d 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -440,7 +440,7 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); - let scrut_ty = + let constraint_ty = switch (scrut.ty) { | Unknown(_) => map_m(go_pat(~is_synswitch=false, ~co_ctx=CoCtx.empty), ps, m) @@ -450,8 +450,8 @@ and uexp_to_info_map = | ty => Some(ty) }; let (self, m) = - switch (scrut_ty) { - | Some(scrut_ty) => + switch (constraint_ty) { + | Some(constraint_ty) => let pats_to_info_map = (ps: list(UPat.t), m) => { /* Add co-ctxs to patterns */ let (m, final_constraint) = @@ -461,7 +461,7 @@ and uexp_to_info_map = go_pat( ~is_synswitch=false, ~co_ctx, - ~mode=Mode.Ana(scrut_ty), + ~mode=Mode.Ana(constraint_ty), p, m, ) From f780316856dc4d047a2734ad21670564253b7380 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 16:12:31 -0400 Subject: [PATCH 226/229] code simplification --- src/haz3lcore/statics/Statics.re | 94 ++++++++++++++++---------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index fcee5a4b0d..7b4973ddb7 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -454,56 +454,54 @@ and uexp_to_info_map = | Some(constraint_ty) => let pats_to_info_map = (ps: list(UPat.t), m) => { /* Add co-ctxs to patterns */ - let (m, final_constraint) = - List.fold_left( - ((m, acc_constraint), (p, co_ctx)) => { - let p_constraint = - go_pat( - ~is_synswitch=false, - ~co_ctx, - ~mode=Mode.Ana(constraint_ty), - p, - m, - ) - |> fst - |> Info.pat_constraint; - let (p, m) = - go_pat( - ~is_synswitch=false, - ~co_ctx, - ~mode=Mode.Ana(scrut.ty), - p, - m, - ); - let is_redundant = - Incon.is_redundant(p_constraint, acc_constraint); - let self = is_redundant ? Self.Redundant(p.self) : p.self; - let info = - Info.derived_pat( - ~upat=p.term, - ~ctx=p.ctx, - ~co_ctx=p.co_ctx, - ~mode=p.mode, - ~ancestors=p.ancestors, - ~self, - // Mark patterns as redundant at the top level - // because redundancy doesn't make sense in a smaller context - ~constraint_=p_constraint, - ); - ( - // Override the info for the single upat - add_info(p.term.ids, InfoPat(info), m), - is_redundant - ? acc_constraint // Redundant patterns are ignored - : Constraint.Or(p_constraint, acc_constraint), + List.fold_left( + ((m, acc_constraint), (p, co_ctx)) => { + let p_constraint = + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(constraint_ty), + p, + m, + ) + |> fst + |> Info.pat_constraint; + let (p, m) = + go_pat( + ~is_synswitch=false, + ~co_ctx, + ~mode=Mode.Ana(scrut.ty), + p, + m, ); - }, - (m, Constraint.Falsity), - List.combine(ps, e_co_ctxs), - ); - (final_constraint, m); + let is_redundant = + Incon.is_redundant(p_constraint, acc_constraint); + let self = is_redundant ? Self.Redundant(p.self) : p.self; + let info = + Info.derived_pat( + ~upat=p.term, + ~ctx=p.ctx, + ~co_ctx=p.co_ctx, + ~mode=p.mode, + ~ancestors=p.ancestors, + ~self, + // Mark patterns as redundant at the top level + // because redundancy doesn't make sense in a smaller context + ~constraint_=p_constraint, + ); + ( + // Override the info for the single upat + add_info(p.term.ids, InfoPat(info), m), + is_redundant + ? acc_constraint // Redundant patterns are ignored + : Constraint.Or(p_constraint, acc_constraint), + ); + }, + (m, Constraint.Falsity), + List.combine(ps, e_co_ctxs), + ); }; - let (final_constraint, m) = pats_to_info_map(ps, m); + let (m, final_constraint) = pats_to_info_map(ps, m); let unwrapped_self: Self.exp = Common(Self.match(ctx, e_tys, branch_ids)); let is_exhaustive = Incon.is_exhaustive(final_constraint); From 58f568b068b29b9106874164f6abce7667fc8608 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Sun, 5 May 2024 16:18:53 -0400 Subject: [PATCH 227/229] code simplification --- src/haz3lcore/statics/Statics.re | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 7b4973ddb7..b445c41452 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -440,6 +440,8 @@ and uexp_to_info_map = let e_tys = List.map(Info.exp_ty, es); let e_co_ctxs = List.map2(CoCtx.mk(ctx), p_ctxs, List.map(Info.exp_co_ctx, es)); + let unwrapped_self: Self.exp = + Common(Self.match(ctx, e_tys, branch_ids)); let constraint_ty = switch (scrut.ty) { | Unknown(_) => @@ -502,8 +504,6 @@ and uexp_to_info_map = ); }; let (m, final_constraint) = pats_to_info_map(ps, m); - let unwrapped_self: Self.exp = - Common(Self.match(ctx, e_tys, branch_ids)); let is_exhaustive = Incon.is_exhaustive(final_constraint); let self = is_exhaustive ? unwrapped_self : InexhaustiveMatch(unwrapped_self); @@ -522,7 +522,7 @@ and uexp_to_info_map = List.combine(ps, e_co_ctxs), m, ); - (Common(Self.match(ctx, e_tys, branch_ids)), m); + (unwrapped_self, m); }; add'(~self, ~co_ctx=CoCtx.union([scrut.co_ctx] @ e_co_ctxs), m); | TyAlias(typat, utyp, body) => From f304a31e4822fb2e0b4670b9ee78d53b6060466e Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 7 May 2024 16:02:35 -0400 Subject: [PATCH 228/229] further upstreamed --- src/haz3lcore/statics/Statics.re | 5 ++++- src/haz3lweb/ScratchSlide.re | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/haz3lcore/statics/Statics.re b/src/haz3lcore/statics/Statics.re index 29f4c27ce9..637dbdf6b0 100644 --- a/src/haz3lcore/statics/Statics.re +++ b/src/haz3lcore/statics/Statics.re @@ -46,7 +46,10 @@ module Map = { * when iterating over the info_map should have no * effect, beyond supressing the resulting Not_found exs */ switch (Id.Map.find_opt(id, term_ranges)) { - | Some(_) when Info.is_error(info) => [id, ...acc] + | Some(_) when Info.is_error(info) && id == Info.id_of(info) => [ + id, + ...acc, + ] | _ => acc }, info_map, diff --git a/src/haz3lweb/ScratchSlide.re b/src/haz3lweb/ScratchSlide.re index 6d6214921d..09860711ed 100644 --- a/src/haz3lweb/ScratchSlide.re +++ b/src/haz3lweb/ScratchSlide.re @@ -51,8 +51,6 @@ let mk_statics = let term = MakeTerm.from_zip_for_sem(editor.state.zipper) |> fst; let info_map = Interface.Statics.mk_map_ctx(settings.core, ctx_init, term); let error_ids = - info_map - |> Id.Map.filter((id, info) => id == Info.id_of(info)) - |> Statics.Map.error_ids(editor.state.meta.term_ranges); + Statics.Map.error_ids(editor.state.meta.term_ranges, info_map); {term, info_map, error_ids}; }; From d6d61c8cb43db1d11778d965aed5262cb3a3c4f9 Mon Sep 17 00:00:00 2001 From: Jiezhong Yang Date: Tue, 14 May 2024 13:55:27 -0400 Subject: [PATCH 229/229] code clean --- src/haz3lcore/statics/TypBase.re | 100 ++++++------------------------- 1 file changed, 19 insertions(+), 81 deletions(-) diff --git a/src/haz3lcore/statics/TypBase.re b/src/haz3lcore/statics/TypBase.re index 576f368b6b..58690c3aec 100644 --- a/src/haz3lcore/statics/TypBase.re +++ b/src/haz3lcore/statics/TypBase.re @@ -559,21 +559,10 @@ and Ctx: { kind: Kind.t, }; - [@deriving (show({with_path: false}), sexp, yojson)] - type constructor_entry = { - name: Var.t, - id: Id.t, - typ: Typ.t, - /* Temporary variables. Better implementation is a TO-DO. */ - nth: int, - num_variants: int, - }; - [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ - | ConstructorEntry(constructor_entry) + | ConstructorEntry(var_entry) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -587,7 +576,7 @@ and Ctx: { let lookup_alias: (t, TypVar.t) => option(Typ.t); let get_id: entry => Id.t; let lookup_var: (t, string) => option(var_entry); - let lookup_ctr: (t, string) => option(constructor_entry); + let lookup_ctr: (t, string) => option(var_entry); let is_alias: (t, TypVar.t) => bool; let is_abstract: (t, TypVar.t) => bool; let add_ctrs: (t, TypVar.t, Id.t, Typ.sum_map) => t; @@ -610,21 +599,10 @@ and Ctx: { kind: Kind.t, }; - [@deriving (show({with_path: false}), sexp, yojson)] - type constructor_entry = { - name: Var.t, - id: Id.t, - typ: Typ.t, - /* Temporary variables. Better implementation is a TO-DO. */ - nth: int, - num_variants: int, - }; - [@deriving (show({with_path: false}), sexp, yojson)] type entry = | VarEntry(var_entry) - // | ConstructorEntry(var_entry, Constraint.t => Constraint.t) /* obselete because of dependency cycle */ - | ConstructorEntry(constructor_entry) + | ConstructorEntry(var_entry) | TVarEntry(tvar_entry); [@deriving (show({with_path: false}), sexp, yojson)] @@ -670,7 +648,7 @@ and Ctx: { ctx, ); - let lookup_ctr = (ctx: t, name: string): option(constructor_entry) => + let lookup_ctr = (ctx: t, name: string): option(var_entry) => List.find_map( fun | ConstructorEntry(t) when t.name == name => Some(t) @@ -690,61 +668,21 @@ and Ctx: { | _ => false }; - let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => { - // let (ctx, _, _) = - // List.fold_left( - // ((ctx, nth, wrap), (ctr, typ)) => { - // // List.length(ctrs) == 0: EmptyHole - // // List.length(ctrs) == 1: Type variable not found - // assert(List.length(ctrs) > 1); - - // // List.length(ctrs) == 2: - // // nth == 0: xi => InjL(xi) - // // nth == 1: xi => InjR(InjL(xi)) - // // nth == 2: xi => InjR(InjR(xi)) - // let constraint_ctor = xi => - // wrap(nth == List.length(ctrs) - 1 ? Constraint.InjL(xi) : xi); - // let entry = - // ConstructorEntry( - // { - // name: ctr, - // id, - // typ: - // switch (typ) { - // | None => Var(name) - // | Some(typ) => Arrow(typ, Var(name)) - // }, - // }, - // constraint_ctor, - // ); - // ([entry, ...ctx], nth + 1, xi => wrap(Constraint.InjR(xi))); - // }, - // (ctx, 0, Fun.id), - // ctrs, - // ); - let num_variants = List.length(ctrs); - let (ctx, _) = - List.fold_left( - ((ctx, nth), (ctr, typ)) => { - let entry = - ConstructorEntry({ - name: ctr, - id, - typ: - switch (typ) { - | None => Var(name) - | Some(typ) => Arrow(typ, Var(name)) - }, - nth, - num_variants, - }); - ([entry, ...ctx], nth + 1); - }, - (ctx, 0), - ctrs, - ); - ctx; - }; + let add_ctrs = (ctx: t, name: TypVar.t, id: Id.t, ctrs: Typ.sum_map): t => + List.map( + ((ctr, typ)) => + ConstructorEntry({ + name: ctr, + id, + typ: + switch (typ) { + | None => Var(name) + | Some(typ) => Arrow(typ, Var(name)) + }, + }), + ctrs, + ) + @ ctx; let subtract_prefix = (ctx: t, prefix_ctx: t): option(t) => { // NOTE: does not check that the prefix is an actual prefix