Skip to content

Commit 24d2a57

Browse files
committed
Remove support for type annotations for non-empty map and set literals
1 parent fade87a commit 24d2a57

8 files changed

Lines changed: 43 additions & 84 deletions

File tree

src/lustre/lustreAstHelpers.ml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,12 +2084,6 @@ let pos_of_type ty = match ty with
20842084
| TupleType (p, _) | RecordType (p, _, _)
20852085
| RefinementType (p, _, _) -> p
20862086

2087-
let rec find_type_annotation e = match e with
2088-
| StructUpdate (_, e, _, _) -> find_type_annotation e
2089-
| EmptySet (_, ta) -> ta
2090-
| EmptyMap (p, Some (kt, vt)) -> Some (Map (p, kt, vt))
2091-
| _ -> None
2092-
20932087
(* Return the node_id of a declaration if it is a node/func/contract decl *)
20942088
let node_id_of_decl = function
20952089
| NodeDecl (_, (id, _, _, _, _, _, _, _, _))

src/lustre/lustreAstHelpers.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,4 @@ val contains_subtype_satisfying: (lustre_type -> bool) -> lustre_type -> bool
212212
val pos_of_type: lustre_type -> Lib.position
213213
(** `pos_of_type ty` returns the position of `ty` *)
214214

215-
val find_type_annotation: expr -> lustre_type option
216-
(** `find_type_annotation e` recurses down `StructUpdates` to find the leaf-level type annotation, if one exists *)
217-
218215
val node_id_of_decl: declaration -> NodeId.t option

src/lustre/lustreAstNormalizer.ml

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,29 +2284,17 @@ and normalize_expr ?guard info (node_id : NI.t option) map =
22842284
let nexpr = A.Ident (pos, name) in
22852285
nexpr, union (union gids1 gids2) gids3, warnings1 @ warnings2
22862286
| StructUpdate (pos, expr1, [A.MapIndex (_, expr2)], Some expr3) as expr ->
2287-
let gids1, warnings1 = match AH.find_type_annotation expr1 with
2288-
| Some (Map (_, kt, vt)) ->
2289-
let gids, warnings = mk_fresh_refinement_type_constraint Local info map pos node_id expr2 kt in
2290-
let gids', warnings' = mk_fresh_refinement_type_constraint Local info map pos node_id expr3 vt in
2291-
let gids'', warnings'' = mk_fresh_subrange_constraint ~force_prop:true Local info map pos node_id expr2 kt in
2292-
let gids''', warnings''' = mk_fresh_subrange_constraint ~force_prop:true Local info map pos node_id expr3 vt in
2293-
let gids = List.fold_left union (empty ()) [gids; gids'; gids''; gids'''] in
2294-
let warnings = warnings @ warnings' @ warnings'' @ warnings''' in
2295-
gids, warnings
2296-
| None -> empty (), []
2297-
| _ -> assert false (* Type annotation must be `Map` type, enforced by the parser *)
2298-
in
22992287
(* Don't supply the guard when normalizing subexpressions,
23002288
because we need to generate oracle variables in initial step
23012289
if there are unguarded pres *)
2302-
let nexpr1, gids2, _ = normalize_expr info node_id map expr1 in
2303-
let nexpr2, gids3, _ = normalize_expr info node_id map expr2 in
2304-
let nexpr3, gids4, _ = normalize_expr info node_id map expr3 in
2290+
let nexpr1, gids1, _ = normalize_expr info node_id map expr1 in
2291+
let nexpr2, gids2, _ = normalize_expr info node_id map expr2 in
2292+
let nexpr3, gids3, _ = normalize_expr info node_id map expr3 in
23052293
(* Hacky: to generate correct user-facing warnings, we call normalize_expr
23062294
while supplying the guard, but ignore all other outputs *)
2307-
let _, _, warnings2 = normalize_expr ?guard info node_id map expr1 in
2308-
let _, _, warnings3 = normalize_expr ?guard info node_id map expr2 in
2309-
let _, _, warnings4 = normalize_expr ?guard info node_id map expr3 in
2295+
let _, _, warnings1 = normalize_expr ?guard info node_id map expr1 in
2296+
let _, _, warnings2 = normalize_expr ?guard info node_id map expr2 in
2297+
let _, _, warnings3 = normalize_expr ?guard info node_id map expr3 in
23102298
i := !i + 1;
23112299
let prefix = HString.mk_hstring (string_of_int !i) in
23122300
let name1 = HString.concat2 prefix (HString.mk_hstring "_map_update") in
@@ -2318,30 +2306,23 @@ and normalize_expr ?guard info (node_id : NI.t option) map =
23182306
(* Use base types *)
23192307
let kt = Chk.expand_type_syn_reftype_history_subrange info.context kt |> Result.get_ok in
23202308
let vt = Chk.expand_type_syn_reftype_history_subrange info.context vt |> Result.get_ok in
2321-
let gids5 = { (empty ()) with
2309+
let gids4 = { (empty ()) with
23222310
map_element_updates = [ name1, nexpr1, nexpr2, nexpr3, name2, kt, vt ];
23232311
locals = StringMap.add name2 kt (StringMap.singleton name1 (A.Map (pos, kt, vt)));
23242312
} in
23252313
let nexpr = A.Ident (pos, name1) in
2326-
let gids = List.fold_left union (empty ()) [gids1; gids2; gids3; gids4; gids5] in
2327-
nexpr, gids, warnings1 @ warnings2 @ warnings3 @ warnings4
2314+
let gids = List.fold_left union (empty ()) [gids1; gids2; gids3; gids4] in
2315+
nexpr, gids, warnings1 @ warnings2 @ warnings3
23282316
| StructUpdate (pos, expr1, [A.SetIndex (_, expr2)], None) as expr ->
2329-
let gids1, warnings1 = match AH.find_type_annotation expr1 with
2330-
| Some ty ->
2331-
let gids, warnings = mk_fresh_refinement_type_constraint Local info map pos node_id expr2 ty in
2332-
let gids', warnings' = mk_fresh_subrange_constraint ~force_prop:true Local info map pos node_id expr2 ty in
2333-
union gids gids', warnings @ warnings'
2334-
| None -> empty (), []
2335-
in
23362317
(* Don't supply the guard when normalizing subexpressions,
23372318
because we need to generate oracle variables in initial step
23382319
if there are unguarded pres *)
2339-
let nexpr1, gids2, _ = normalize_expr info node_id map expr1 in
2340-
let nexpr2, gids3, _ = normalize_expr info node_id map expr2 in
2320+
let nexpr1, gids1, _ = normalize_expr info node_id map expr1 in
2321+
let nexpr2, gids2, _ = normalize_expr info node_id map expr2 in
23412322
(* Hacky: to generate correct user-facing warnings, we call normalize_expr
23422323
while supplying the guard, but ignore all other outputs *)
2343-
let _, _, warnings2 = normalize_expr ?guard info node_id map expr1 in
2344-
let _, _, warnings3 = normalize_expr ?guard info node_id map expr2 in
2324+
let _, _, warnings1 = normalize_expr ?guard info node_id map expr1 in
2325+
let _, _, warnings2 = normalize_expr ?guard info node_id map expr2 in
23452326
i := !i + 1;
23462327
let prefix = HString.mk_hstring (string_of_int !i) in
23472328
let name1 = HString.concat2 prefix (HString.mk_hstring "_set_update") in
@@ -2352,13 +2333,13 @@ and normalize_expr ?guard info (node_id : NI.t option) map =
23522333
in
23532334
(* Use base types *)
23542335
let ty = Chk.expand_type_syn_reftype_history_subrange info.context ty |> Result.get_ok in
2355-
let gids4 = { (empty ()) with
2336+
let gids3 = { (empty ()) with
23562337
set_insertions = [ name1, nexpr1, nexpr2, name2, ty ];
23572338
locals = StringMap.add name2 ty (StringMap.singleton name1 (A.Set (pos, ty)));
23582339
} in
23592340
let nexpr = A.Ident (pos, name1) in
2360-
let gids = List.fold_left union (empty ()) [gids1; gids2; gids3; gids4] in
2361-
nexpr, gids, warnings1 @ warnings2 @ warnings3
2341+
let gids = List.fold_left union (empty ()) [gids1; gids2; gids3] in
2342+
nexpr, gids, warnings1 @ warnings2
23622343

23632344
| RecordProject (pos, expr, i) ->
23642345
let nexpr, gids, warnings = normalize_expr ?guard info node_id map expr in

src/lustre/lustreParser.mly

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -960,38 +960,38 @@ pexpr(Q):
960960
(* An array constructor (not quantified) *)
961961
| e1 = pexpr(Q); CARET; e2 = expr { A.ArrayConstr (mk_pos $startpos, e1, e2) }
962962

963+
(* Empty map *)
964+
| MAP; LSQBRACKET; RSQBRACKET;
965+
ta = map_type_annotation
966+
{ A.EmptyMap (mk_pos $startpos, Some ta) }
967+
963968
(* Map literals *)
964969
| MAP LSQBRACKET
965-
updates = separated_list(SEMICOLON, assign);
970+
updates = separated_nonempty_list(SEMICOLON, assign);
966971
RSQBRACKET
967-
ta = option(map_type_annotation)
968972
{
969-
match ta, updates with
970-
| None, [] ->
971-
let pos = mk_pos $startpos in
972-
fail_at_position pos "Empty map must have a type annotation"
973-
| ta, updates ->
974-
List.fold_left (fun acc (e2, e3) ->
975-
A.StructUpdate (mk_pos $startpos, acc, [A.MapIndex (mk_pos $startpos, e2)], Some e3)
976-
) (A.EmptyMap (mk_pos $startpos, ta)) updates
973+
List.fold_left (fun acc (e2, e3) ->
974+
A.StructUpdate (mk_pos $startpos, acc, [A.MapIndex (mk_pos $startpos, e2)], Some e3)
975+
) (A.EmptyMap (mk_pos $startpos, None)) updates
977976
}
978977

978+
(* Empty set *)
979+
| LCURLYBRACKET
980+
RCURLYBRACKET
981+
ta = type_annotation;
982+
{ A.EmptySet (mk_pos $startpos, Some ta) }
983+
979984
(* Set literals *)
980985
| LCURLYBRACKET
981-
elements = separated_list(COMMA, expr);
986+
elements = separated_nonempty_list(COMMA, expr);
982987
RCURLYBRACKET
983-
ta = option(type_annotation);
984988
{
985-
match ta, elements with
986-
| None, [] ->
987-
let pos = mk_pos $startpos in
988-
fail_at_position pos "Empty set must have a type annotation"
989-
| ta, elements ->
990-
List.fold_left (fun acc e ->
991-
A.StructUpdate (mk_pos $startpos, acc, [A.SetIndex (mk_pos $startpos, e)], None)
992-
) (A.EmptySet (mk_pos $startpos, ta)) elements
989+
List.fold_left (fun acc e ->
990+
A.StructUpdate (mk_pos $startpos, acc, [A.SetIndex (mk_pos $startpos, e)], None)
991+
) (A.EmptySet (mk_pos $startpos, None)) elements
993992
}
994993

994+
(* Map element updates *)
995995
| e1 = pexpr(Q);
996996
LSQBRACKET;
997997
updates = separated_nonempty_list(SEMICOLON, assign);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
node N(x: int) returns (y: set<int>);
22
let
3-
y = { x }@<bool>;
3+
y = { }@<bool>;
44
check x in y;
55
tel

tests/regression/falsifiable/enforce_ty_annots.lus

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/regression/success/empty_map_update_test.lus

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node N () returns (out: map<int, int>)
22
let
3-
out = map[1 := 2; 3 := 4]@<int, int>;
3+
out = map[1 := 2; 3 := 4];
44
check 1 in out;
55
check 3 in out;
66
check forall (i: int) i <> 1 and i <> 3 => not (i in out);

tests/regression/success/set_literals.lus

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ type R = struct { x: int; y: int };
66

77
node N() returns (o: S; o2: set<[int, int]>; o3: set<[[int, int], int]>; o4: set<[int, int]>; o6: set<R>)
88
let
9-
o = { 3, 4 }@<int>;
10-
o2 ={ '(3, 4), '(6, 7) }@<[int, int]>;
9+
o = { 3, 4 };
10+
o2 ={ '(3, 4), '(6, 7) };
1111

1212
check 3 in o;
1313
check 4 in o;
@@ -16,9 +16,9 @@ let
1616
check forall (i: int) i <> 3 and i <> 4 => not (i in o);
1717
check forall (i: [int, int]) i <> '(3, 4) and i <> '(6, 7) => not (i in o2);
1818

19-
o3 = { '('(3, 4), 5), '('(6, 7), 8) }@<[[int, int], int]>;
20-
o4 = { '(3, 4), '(7, 8) }@<[int, int]>;
21-
o6 = { R {x = 3; y = 4}, R {x = 5; y = 6} }@<R>;
19+
o3 = { '('(3, 4), 5), '('(6, 7), 8) };
20+
o4 = { '(3, 4), '(7, 8) };
21+
o6 = { R {x = 3; y = 4}, R {x = 5; y = 6} };
2222

2323
check '('(3, 4), 5) in o3;
2424
check '('(6, 7), 8) in o3;

0 commit comments

Comments
 (0)