Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting implementation of incon judgment into Hazel 3. #1094

Merged
merged 11 commits into from
Oct 22, 2023
15 changes: 13 additions & 2 deletions src/haz3lcore/dynamics/DH.re
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module rec DHExp: {
| Prj(t, int)
| Constructor(string)
| ConsistentCase(case)
| InexhaustiveCase(MetaVar.t, HoleInstanceId.t, case)
| Cast(t, Typ.t, Typ.t)
| FailedCast(t, Typ.t, Typ.t)
| InvalidOperation(t, InvalidOperationError.t)
Expand Down Expand Up @@ -87,6 +88,7 @@ module rec DHExp: {
| Prj(t, int)
| Constructor(string)
| ConsistentCase(case)
| InexhaustiveCase(MetaVar.t, HoleInstanceId.t, case)
| Cast(t, Typ.t, Typ.t)
| FailedCast(t, Typ.t, Typ.t)
| InvalidOperation(t, InvalidOperationError.t)
Expand Down Expand Up @@ -126,6 +128,7 @@ module rec DHExp: {
| Prj(_) => "Prj"
| Constructor(_) => "Constructor"
| ConsistentCase(_) => "ConsistentCase"
| InexhaustiveCase(_, _, _) => "InexhaustiveCase"
| InconsistentBranches(_, _, _) => "InconsistentBranches"
| Cast(_, _, _) => "Cast"
| FailedCast(_, _, _) => "FailedCast"
Expand Down Expand Up @@ -174,6 +177,12 @@ module rec DHExp: {
ConsistentCase(
Case(strip_casts(a), List.map(strip_casts_rule, rs), b),
)
| InexhaustiveCase(u, i, Case(scrut, rules, n)) =>
InexhaustiveCase(
u,
i,
Case(strip_casts(scrut), List.map(strip_casts_rule, rules), n),
)
| InconsistentBranches(u, i, Case(scrut, rules, n)) =>
InconsistentBranches(
u,
Expand Down Expand Up @@ -284,15 +293,17 @@ module rec DHExp: {
| (
InconsistentBranches(u1, i1, case1),
InconsistentBranches(u2, i2, case2),
) =>
)
| (InexhaustiveCase(u1, i1, case1), InexhaustiveCase(u2, i2, case2)) =>
u1 == u2 && i1 == i2 && fast_equal_case(case1, case2)
| (EmptyHole(_), _)
| (NonEmptyHole(_), _)
| (ExpandingKeyword(_), _)
| (FreeVar(_), _)
| (InvalidText(_), _)
| (Closure(_), _)
| (InconsistentBranches(_), _) => false
| (InconsistentBranches(_), _)
| (InexhaustiveCase(_), _) => false
};
}
and fast_equal_case = (Case(d1, rules1, i1), Case(d2, rules2, i2)) => {
Expand Down
5 changes: 5 additions & 0 deletions src/haz3lcore/dynamics/Elaborator.re
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ let cast = (ctx: Ctx.t, mode: Mode.t, self_ty: Typ.t, d: DHExp.t) =>
}
/* Forms with special ana rules but no particular typing requirements */
| ConsistentCase(_)
| InexhaustiveCase(_)
| InconsistentBranches(_)
| Sequence(_)
| Let(_)
Expand Down Expand Up @@ -271,7 +272,11 @@ let rec dhexp_of_uexp =
| InHole(
InexhaustiveMatch(Some(Common(Inconsistent(Internal(_))))),
) =>
// TODO: review
// If multiple errors are associated with a case expression,
// DHExp.InconsistentBranches is prioritized.
DHExp.InconsistentBranches(id, 0, d)
| InHole(InexhaustiveMatch(_)) => DHExp.InexhaustiveCase(id, 0, d)
| _ => ConsistentCase(d)
};
| TyAlias(_, _, e) => dhexp_of_uexp(m, e)
Expand Down
8 changes: 8 additions & 0 deletions src/haz3lcore/dynamics/Evaluator.re
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ and matches_cast_Sum =
| BinFloatOp(_)
| BinStringOp(_)
| InconsistentBranches(_)
| InexhaustiveCase(_)
| EmptyHole(_)
| NonEmptyHole(_)
| FailedCast(_, _, _)
Expand Down Expand Up @@ -409,6 +410,7 @@ and matches_cast_Tuple =
| Prj(_) => DoesNotMatch
| Constructor(_) => DoesNotMatch
| ConsistentCase(_)
| InexhaustiveCase(_)
| InconsistentBranches(_) => IndetMatch
| EmptyHole(_) => IndetMatch
| NonEmptyHole(_) => IndetMatch
Expand Down Expand Up @@ -544,6 +546,7 @@ and matches_cast_Cons =
| Prj(_) => DoesNotMatch
| Constructor(_) => DoesNotMatch
| ConsistentCase(_)
| InexhaustiveCase(_)
| InconsistentBranches(_) => IndetMatch
| EmptyHole(_) => IndetMatch
| NonEmptyHole(_) => IndetMatch
Expand Down Expand Up @@ -988,6 +991,11 @@ let rec evaluate: (ClosureEnvironment.t, DHExp.t) => m(EvaluatorResult.t) =
Indet(Closure(env, InconsistentBranches(u, i, Case(d1, rules, n))))
|> return

| InexhaustiveCase(u, i, Case(d1, rules, n)) =>
//TODO: revisit this, consider some kind of dynamic casting
Indet(Closure(env, InexhaustiveCase(u, i, Case(d1, rules, n))))
|> return

| EmptyHole(u, i) => Indet(Closure(env, EmptyHole(u, i))) |> return

| NonEmptyHole(reason, u, i, d1) =>
Expand Down
11 changes: 10 additions & 1 deletion src/haz3lcore/dynamics/EvaluatorPost.re
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ let rec pp_eval = (d: DHExp.t): m(DHExp.t) =>
| BoundVar(_)
| Let(_)
| ConsistentCase(_)
| InexhaustiveCase(_)
| Fun(_)
| EmptyHole(_)
| NonEmptyHole(_)
Expand Down Expand Up @@ -412,6 +413,13 @@ and pp_uneval = (env: ClosureEnvironment.t, d: DHExp.t): m(DHExp.t) =>
let* i = hii_add_instance(u, env);
Closure(env, InconsistentBranches(u, i, Case(scrut, rules, case_i)))
|> return;

| InexhaustiveCase(u, _, Case(scrut, rules, case_i)) =>
let* scrut = pp_uneval(env, scrut);
let* rules = pp_uneval_rules(env, rules);
let* i = hii_add_instance(u, env);
Closure(env, InexhaustiveCase(u, i, Case(scrut, rules, case_i)))
|> return;
}

and pp_uneval_rules =
Expand Down Expand Up @@ -501,7 +509,8 @@ let rec track_children_of_hole =
| NonEmptyHole(_, u, i, d) =>
let hii = track_children_of_hole(hii, parent, d);
hii |> HoleInstanceInfo.add_parent((u, i), parent);
| InconsistentBranches(u, i, Case(scrut, rules, _)) =>
| InconsistentBranches(u, i, Case(scrut, rules, _))
| InexhaustiveCase(u, i, Case(scrut, rules, _)) =>
let hii = track_children_of_hole(hii, parent, scrut);
let hii = track_children_of_hole_rules(hii, parent, rules);
hii |> HoleInstanceInfo.add_parent((u, i), parent);
Expand Down
4 changes: 4 additions & 0 deletions src/haz3lcore/dynamics/Substitution.re
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ let rec subst_var = (d1: DHExp.t, x: Var.t, d2: DHExp.t): DHExp.t =>
let d3 = subst_var(d1, x, d3);
let rules = subst_var_rules(d1, x, rules);
ConsistentCase(Case(d3, rules, n));
| InexhaustiveCase(u, i, Case(d3, rules, n)) =>
let d3 = subst_var(d1, x, d3);
let rules = subst_var_rules(d1, x, rules);
InexhaustiveCase(u, i, Case(d3, rules, n));
| InconsistentBranches(u, i, Case(d3, rules, n)) =>
let d3 = subst_var(d1, x, d3);
let rules = subst_var_rules(d1, x, rules);
Expand Down
1 change: 1 addition & 0 deletions src/haz3lweb/view/dhcode/DHCode.re
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ let view_of_layout = (~font_metrics: FontMetrics.t, l: DHLayout.t): Node.t => {
([with_cls("exception", txt)], ds)
| NonEmptyHole(_)
| InconsistentBranches(_)
| InexhaustiveCase(_)
| Invalid(_) =>
let offset = start.col - indent;
let decoration =
Expand Down
1 change: 1 addition & 0 deletions src/haz3lweb/view/dhcode/layout/DHAnnot.re
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type t =
| NonEmptyHole(ErrStatus.HoleReason.t, HoleInstance.t)
| VarHole(VarErrStatus.HoleReason.t, HoleInstance.t)
| InconsistentBranches(HoleInstance.t)
| InexhaustiveCase(HoleInstance.t)
| Invalid(HoleInstance.t)
| FailedCastDelim
| FailedCastDecoration
Expand Down
1 change: 1 addition & 0 deletions src/haz3lweb/view/dhcode/layout/DHAnnot.rei
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type t =
| NonEmptyHole(ErrStatus.HoleReason.t, HoleInstance.t)
| VarHole(VarErrStatus.HoleReason.t, HoleInstance.t)
| InconsistentBranches(HoleInstance.t)
| InexhaustiveCase(HoleInstance.t)
| Invalid(HoleInstance.t)
| FailedCastDelim
| FailedCastDecoration
Expand Down
3 changes: 3 additions & 0 deletions src/haz3lweb/view/dhcode/layout/DHDoc_Exp.re
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ let rec precedence = (~show_casts: bool, d: DHExp.t) => {
| Let(_)
| FixF(_)
| ConsistentCase(_)
| InexhaustiveCase(_)
| InconsistentBranches(_) => DHDoc_common.precedence_max
| BinBoolOp(op, _, _) => precedence_bin_bool_op(op)
| BinIntOp(op, _, _) => precedence_bin_int_op(op)
Expand Down Expand Up @@ -175,6 +176,8 @@ let rec mk =
| InvalidText(u, i, t) => DHDoc_common.mk_InvalidText(t, (u, i))
| InconsistentBranches(u, i, Case(dscrut, drs, _)) =>
go_case(dscrut, drs) |> annot(DHAnnot.InconsistentBranches((u, i)))
| InexhaustiveCase(u, i, Case(dscrut, drs, _)) =>
go_case(dscrut, drs) |> annot(DHAnnot.InexhaustiveCase((u, i)))
| BoundVar(x) => text(x)
| Constructor(name) => DHDoc_common.mk_ConstructorLit(name)
| BoolLit(b) => DHDoc_common.mk_BoolLit(b)
Expand Down
Loading