Skip to content

Commit

Permalink
Merge pull request #1087 from daniel-larraz/check-bound-var-type
Browse files Browse the repository at this point in the history
Check type of bound variables in quantified expressions
  • Loading branch information
daniel-larraz authored Aug 13, 2024
2 parents 0b8dc93 + f0f9143 commit d1501e2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/lustre/lustreTypeChecker.ml
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,14 @@ let rec infer_type_expr: tc_context -> HString.t option -> LA.expr -> (tc_type *

(* Quantified expressions *)
| LA.Quantifier (_, _, qs, e) ->
let* warnings1 =
R.seq (List.map (fun (_, _, ty) ->
check_type_well_formed ctx Local nname true ty) qs)
in
let extn_ctx = List.fold_left union ctx
(List.map (fun (_, i, ty) -> singleton_ty i ty) qs) in
infer_type_expr extn_ctx nname e
let* ty, warnings2 = infer_type_expr extn_ctx nname e in
R.ok (ty, List.flatten warnings1 @ warnings2)

| AnyOp _ -> assert false
(* Already desugared in lustreDesugarAnyOps *)
Expand Down Expand Up @@ -1087,7 +1092,11 @@ and check_type_expr: tc_context -> HString.t option -> LA.expr -> tc_type -> ([>
else type_error pos (ExpectedIntegerTypeForArrayIndex index_type)

(* Quantified expressions *)
| Quantifier (_, _, qs, e) ->
| Quantifier (_, _, qs, e) -> (
let* warnings1 =
R.seq (List.map (fun (_, _, ty) ->
check_type_well_formed ctx Local nname true ty) qs)
in
(* Disallow quantification over abstract types *)
let* _ = R.seq_ (List.map (fun (pos, id, ty) ->
if type_contains_abstract ctx ty
Expand All @@ -1098,8 +1107,9 @@ and check_type_expr: tc_context -> HString.t option -> LA.expr -> tc_type -> ([>
) qs) in
let extn_ctx = List.fold_left union ctx
(List.map (fun (_, i, ty) -> singleton_ty i ty) qs) in
check_type_expr extn_ctx nname e exp_ty

let* warnings2 = check_type_expr extn_ctx nname e exp_ty in
R.ok (List.flatten warnings1 @ warnings2)
)
| AnyOp _ -> assert false
(* Already desugared in lustreDesugarAnyOps *)
(*let extn_ctx = union ctx (singleton_ty i ty) in
Expand Down
5 changes: 5 additions & 0 deletions tests/ounit/lustre/lustreTypeChecker/bad_bound_var_type.lus
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

node N() returns (ok: bool);
let
check forall (x: subrange [0.0,5.0] of int) x>=0;
tel
4 changes: 4 additions & 0 deletions tests/ounit/lustre/testLustreFrontend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,10 @@ let _ = run_test_tt_main ("frontend LustreTypeChecker error tests" >::: [
match load_file "./lustreTypeChecker/type-grammer.lus" with
| Error (`LustreTypeCheckerError (_, ExpectedIntegerExpression _)) -> true
| _ -> false);
mk_test "test invalid type for bound variable" (fun () ->
match load_file "./lustreTypeChecker/bad_bound_var_type.lus" with
| Error (`LustreTypeCheckerError (_, ExpectedIntegerExpression _)) -> true
| _ -> false);
mk_test "test invalid expression for array size 1" (fun () ->
match load_file "./lustreTypeChecker/node_call_in_array_size_expr.lus" with
| Error (`LustreTypeCheckerError (_, ExpectedConstant _)) -> true
Expand Down

0 comments on commit d1501e2

Please sign in to comment.