@@ -209,6 +209,25 @@ let translate_number (_number : string) (decimal : string) : ts_node =
209209 then leaf_node " nat_number"
210210 else leaf_node " real_number"
211211
212+ (* * For expressions like \A x, y \in Nat : f(x, y), the first x will have
213+ bound_domain variant Domain with an associated expression corresponding
214+ to the set being enumerated, and the second variable y will have
215+ bound_domain variant Ditto without any associated domain information;
216+ this function regroups these into a list of identifiers underneath a
217+ single set expression. It is different from the unditto function which
218+ clones the set expression into the y variable bound_domain. This also
219+ handles unbounded quantification, which is represented by the No_domain
220+ variant and bundled by this function into an option.
221+ *)
222+ let group_bounds (bounds : Expr.T.bound list ) : (ts_node list * Expr.T.expr) list =
223+ let (final_groups, _) = List. fold_right (fun ((_ , _ , domain ) : Expr.T. bound ) ((groups , partial_group ) : ((ts_node list * Expr.T. expr ) list ) * ts_node list ) ->
224+ match domain with
225+ | Ditto -> (groups, leaf_node " identifier" :: partial_group)
226+ | Domain expr -> ((leaf_node " identifier" :: partial_group, expr) :: groups, [] )
227+ | No_domain -> failwith " Encountered unbounded domain when grouping bounds"
228+ ) bounds ([] , [] )
229+ in final_groups
230+
212231(* * Translates the substitution component of INSTANCE statements like s <- expr *)
213232let rec translate_substitution ((hint , expr ) : (Util. hint * Expr.T. expr )) : field_or_node =
214233 Node {
@@ -287,45 +306,55 @@ and translate_jlist (bullet : Expr.T.bullet) (juncts : Expr.T.expr list) : ts_no
287306 children = [leaf (" bullet_" ^ jtype); Node (translate_expr expr)]
288307 }) juncts
289308 }
290- and translate_quantifier_bound ((names , domain ) : (ts_node list * Expr.T. expr )) : ts_node = {
291- name = " quantifier_bound" ;
292- children = List. flatten [
293- field_list " intro" names;
294- [leaf " set_in" ];
295- [Field (" set" , translate_expr domain)]
296- ]
297- }
298309
299310and translate_quantifier_bounds (bounds : Expr.T.bound list ) : ts_node list =
300- let group_bounds ( bounds : Expr.T.bound list ) : (ts_node list * Expr.T.expr) list =
301- let (final_groups, _) = List. fold_right ( fun (( _ , _ , domain ) : Expr.T. bound ) (( groups , partial_group ) : (( ts_node list * Expr.T. expr ) list ) * ts_node list ) ->
302- match domain with
303- | Ditto -> (groups, leaf_node " identifier " :: partial_group)
304- | Domain expr -> ((leaf_node " identifier " :: partial_group, expr) :: groups, [] )
305- | _ -> failwith " unknown quantifier bound type "
306- ) bounds ( [] , [] )
307- in final_groups
311+ let translate_quantifier_bound (( names , domain ) : (ts_node list * Expr.T. expr )) : ts_node = {
312+ name = " quantifier_bound " ;
313+ children = List. flatten [
314+ field_list " intro " names;
315+ [leaf " set_in " ];
316+ [ Field ( " set " , translate_expr domain)]
317+ ]
318+ }
308319 in bounds |> group_bounds |> List. map translate_quantifier_bound
309320
310- and translate_tuple_quantifier_bound ((names , bound_domain ) : Expr.T. tuply_name * Expr.T. bound_domain ) : ts_node =
311- match names, bound_domain with
312- | (Bound_names names , Domain set ) -> {
313- name = " quantifier_bound" ;
314- children = [
315- Field (" intro" , {
316- name = " tuple_of_identifiers" ;
317- children = List. flatten [
318- [leaf " langle_bracket" ];
319- List. map (fun _ -> leaf " identifier" ) names;
320- [leaf " rangle_bracket" ];
321- ]
322- });
323- leaf " set_in" ;
324- Field (" set" , translate_expr set);
325- ]
326- }
327- | (Bound_names _ , Ditto) -> failwith " tuple quantifier ditto"
328- | _ -> failwith " unknown tuple quantifier bound type"
321+ and translate_tuple_quantifier_bounds (bounds : Expr.T.tuply_bound list ) : ts_node list =
322+ let translate_tuple_quantifier_bound ((names , bound_domain ) : Expr.T. tuply_name * Expr.T. bound_domain ) : ts_node =
323+ match names, bound_domain with
324+ | (Bound_names names , Domain set ) -> {
325+ name = " quantifier_bound" ;
326+ children = [
327+ Field (" intro" , {
328+ name = " tuple_of_identifiers" ;
329+ children = List. flatten [
330+ [leaf " langle_bracket" ];
331+ List. map (fun _ -> leaf " identifier" ) names;
332+ [leaf " rangle_bracket" ];
333+ ]
334+ });
335+ leaf " set_in" ;
336+ Field (" set" , translate_expr set);
337+ ]
338+ }
339+ | (Bound_name _ , Domain set ) -> {
340+ name = " quantifier_bound" ;
341+ children = [
342+ Field (" intro" , {
343+ name = " tuple_of_identifiers" ;
344+ children = [
345+ leaf " langle_bracket" ;
346+ field_leaf " intro" " identifier" ;
347+ leaf " rangle_bracket" ;
348+ ]
349+ });
350+ leaf " set_in" ;
351+ Field (" set" , translate_expr set);
352+ ]
353+ }
354+ | (Bound_names _ , Ditto) -> failwith " multiple_names_ditto"
355+ | (Bound_name _ , Ditto) -> leaf_node " single_name_ditto"
356+ | (_ , No_domain) -> failwith " Tuple quantifiers must have a domain; this should not be representable"
357+ in List. map translate_tuple_quantifier_bound bounds
329358
330359and translate_case_arm (index : int ) ((pred , expr ) : Expr.T. expr * Expr.T. expr ) : field_or_node list =
331360 let case = Node {
@@ -438,20 +467,22 @@ and translate_set_filter (_name : Util.hint) (set : Expr.T.expr) (filter : Expr.
438467 ]
439468}
440469
470+ and translate_tuple_of_identifiers (names : Util.hint list ) : ts_node = {
471+ name = " tuple_of_identifiers" ;
472+ children = List. flatten [
473+ [leaf " langle_bracket" ];
474+ List. map (fun _ -> leaf " identifier" ) names;
475+ [leaf " rangle_bracket" ];
476+ ]
477+ }
478+
441479and translate_tuple_set_filter (names : Util.hint list ) (set : Expr.T.expr ) (filter : Expr.T.expr ) : ts_node = {
442480 name = " set_filter" ;
443481 children = [
444482 Field (" generator" , {
445483 name = " quantifier_bound" ;
446484 children = [
447- Field (" intro" , {
448- name = " tuple_of_identifiers" ;
449- children = List. flatten [
450- [leaf " langle_bracket" ];
451- List. map (fun _ -> leaf " identifier" ) names;
452- [leaf " rangle_bracket" ];
453- ]
454- });
485+ Field (" intro" , translate_tuple_of_identifiers names);
455486 leaf " set_in" ;
456487 Field (" set" , translate_expr set)
457488 ]
@@ -473,17 +504,62 @@ and translate_tuple_set_map (map : Expr.T.expr) (bounds : Expr.T.tuply_bound lis
473504 name = " set_map" ;
474505 children = List. flatten [
475506 [Field (" map" , translate_expr map)];
476- field_list_map " generator" translate_tuple_quantifier_bound bounds ;
507+ bounds |> translate_tuple_quantifier_bounds |> field_list " generator" ;
477508 ]
478509}
479510
480- and translate_bounded_quantification (quantifier : Expr.T.quantifier ) (bounds : Expr.T.bound list ) (expr : Expr.T.expr ) : ts_node =
481- let bounds = Expr.T. unditto bounds in {
511+ and translate_quantification (quantifier : Expr.T.quantifier ) (bounds : Expr.T.bound list ) (body : Expr.T.expr ) : ts_node =
512+ let is_bound (bounds : Expr.T.bound list ) : bool =
513+ List. for_all (fun (_ , _ , domain ) -> match (domain : Expr.T.bound_domain ) with | No_domain -> false | _ -> true ) bounds
514+ in if is_bound bounds then {
515+ name = " bounded_quantification" ;
516+ children = List. flatten [
517+ [field_leaf " quantifier" (match quantifier with | Forall -> " forall" | Exists -> " exists" )];
518+ bounds |> translate_quantifier_bounds |> field_list " bound" ;
519+ [Field (" expression" , translate_expr body)];
520+ ]
521+ } else {
522+ name = " unbounded_quantification" ;
523+ children = List. flatten [
524+ [field_leaf " quantifier" (match quantifier with | Forall -> " forall" | Exists -> " exists" )];
525+ List. map (fun _ -> field_leaf " intro" " identifier" ) bounds;
526+ [Field (" expression" , translate_expr body)];
527+ ]
528+ }
529+
530+ and translate_tuple_bounded_quantification (quantifier : Expr.T.quantifier ) (bounds : Expr.T.tuply_bound list ) (body : Expr.T.expr ) : ts_node = {
482531 name = " bounded_quantification" ;
483532 children = List. flatten [
484533 [field_leaf " quantifier" (match quantifier with | Forall -> " forall" | Exists -> " exists" )];
485- field_list " generator" (translate_quantifier_bounds bounds);
486- [Field (" expression" , translate_expr expr)];
534+ bounds |> translate_tuple_quantifier_bounds |> field_list " bound" ;
535+ [Field (" expression" , translate_expr body)];
536+ ]
537+ }
538+
539+ and translate_temporal_quantification (quantifier : Expr.T.quantifier ) (names : Util.hints ) (body : Expr.T.expr ) : ts_node = {
540+ name = " unbounded_quantification" ;
541+ children = List. flatten [
542+ [field_leaf " quantifier" (match quantifier with | Forall -> " temporal_forall" | Exists -> " temporal_exists" )];
543+ List. map (fun _ -> field_leaf " intro" " identifier" ) names;
544+ [Field (" expression" , translate_expr body)];
545+ ]
546+ }
547+
548+ and translate_choose (_name : Util.hint ) (set : Expr.T.expr option ) (body : Expr.T.expr ) : ts_node = {
549+ name = " choose" ;
550+ children = List. flatten [
551+ [field_leaf " intro" " identifier" ];
552+ (match set with | Some expr -> [leaf " set_in" ; Field (" set" , translate_expr expr)] | None -> [] );
553+ [Field (" expression" , translate_expr body)]
554+ ]
555+ }
556+
557+ and translate_tuple_choose (names : Util.hint list ) (set : Expr.T.expr option ) (body : Expr.T.expr ) : ts_node = {
558+ name = " choose" ;
559+ children = List. flatten [
560+ [Field (" intro" , translate_tuple_of_identifiers names)];
561+ (match set with | Some expr -> [leaf " set_in" ; Field (" set" , translate_expr expr)] | None -> [] );
562+ [Field (" expression" , translate_expr body)]
487563 ]
488564}
489565
@@ -504,7 +580,11 @@ and translate_expr (expr : Expr.T.expr) : ts_node =
504580 | SetStTuply (names , set , filter ) -> translate_tuple_set_filter names set filter
505581 | SetOf (map , bounds ) -> translate_set_map map bounds
506582 | SetOfTuply (map , bounds ) -> translate_tuple_set_map map bounds
507- | Quant (quantifier , bounds , expr ) -> translate_bounded_quantification quantifier bounds expr
583+ | Quant (quantifier , bounds , expr ) -> translate_quantification quantifier bounds expr
584+ | QuantTuply (quantifier , bounds , expr ) -> translate_tuple_bounded_quantification quantifier bounds expr
585+ | Tquant (quantifier , hints , expr ) -> translate_temporal_quantification quantifier hints expr
586+ | Choose (name , set , expr ) -> translate_choose name set expr
587+ | ChooseTuply (names , set , expr ) -> translate_tuple_choose names set expr
508588 | Tuple expr_ls -> {
509589 name = " tuple_literal" ;
510590 children = [leaf " langle_bracket" ] @ (node_list_map translate_expr expr_ls) @ [leaf " rangle_bracket" ]
0 commit comments