src/HOL/Tools/inductive_codegen.ML
changeset 15061 61a52739cd82
parent 15031 726dc9146bb1
child 15126 54ae6c6ef3b1
equal deleted inserted replaced
15060:7b4abcfae4e1 15061:61a52739cd82
   329         val (nvs', t') = distinct_v (nvs, t);
   329         val (nvs', t') = distinct_v (nvs, t);
   330         val (nvs'', u') = distinct_v (nvs', u);
   330         val (nvs'', u') = distinct_v (nvs', u);
   331       in (nvs'', t' $ u') end
   331       in (nvs'', t' $ u') end
   332   | distinct_v x = x;
   332   | distinct_v x = x;
   333 
   333 
   334 fun compile_match nvs eq_ps out_ps success_p fail_p =
   334 fun is_exhaustive (Var _) = true
       
   335   | is_exhaustive (Const ("Pair", _) $ t $ u) =
       
   336       is_exhaustive t andalso is_exhaustive u
       
   337   | is_exhaustive _ = false;
       
   338 
       
   339 fun compile_match nvs eq_ps out_ps success_p can_fail =
   335   let val eqs = flat (separate [Pretty.str " andalso", Pretty.brk 1]
   340   let val eqs = flat (separate [Pretty.str " andalso", Pretty.brk 1]
   336     (map single (flat (map (mk_eq o snd) nvs) @ eq_ps)));
   341     (map single (flat (map (mk_eq o snd) nvs) @ eq_ps)));
   337   in
   342   in
   338     Pretty.block
   343     Pretty.block
   339      ([Pretty.str "(fn ", mk_tuple out_ps, Pretty.str " =>", Pretty.brk 1] @
   344      ([Pretty.str "(fn ", mk_tuple out_ps, Pretty.str " =>", Pretty.brk 1] @
   340       (Pretty.block ((if eqs=[] then [] else Pretty.str "if " ::
   345       (Pretty.block ((if eqs=[] then [] else Pretty.str "if " ::
   341          [Pretty.block eqs, Pretty.brk 1, Pretty.str "then "]) @
   346          [Pretty.block eqs, Pretty.brk 1, Pretty.str "then "]) @
   342          (success_p ::
   347          (success_p ::
   343           (if eqs=[] then [] else [Pretty.brk 1, Pretty.str "else ", fail_p]))) ::
   348           (if eqs=[] then [] else [Pretty.brk 1, Pretty.str "else Seq.empty"]))) ::
   344        [Pretty.brk 1, Pretty.str "| _ => ", fail_p, Pretty.str ")"]))
   349        (if can_fail then
       
   350           [Pretty.brk 1, Pretty.str "| _ => Seq.empty)"]
       
   351         else [Pretty.str ")"])))
   345   end;
   352   end;
   346 
   353 
   347 fun modename thy s (iss, is) = space_implode "__"
   354 fun modename thy s (iss, is) = space_implode "__"
   348   (mk_const_id (sign_of thy) s ::
   355   (mk_const_id (sign_of thy) s ::
   349     map (space_implode "_" o map string_of_int) (mapfilter I iss @ [is]));
   356     map (space_implode "_" o map string_of_int) (mapfilter I iss @ [is]));
   399               (invoke_codegen thy dep false) (gr3, out_ts''');
   406               (invoke_codegen thy dep false) (gr3, out_ts''');
   400             val (gr5, eq_ps') = foldl_map compile_eq (gr4, eqs')
   407             val (gr5, eq_ps') = foldl_map compile_eq (gr4, eqs')
   401           in
   408           in
   402             (gr5, compile_match (snd nvs) (eq_ps @ eq_ps') out_ps'
   409             (gr5, compile_match (snd nvs) (eq_ps @ eq_ps') out_ps'
   403               (Pretty.block [Pretty.str "Seq.single", Pretty.brk 1, mk_tuple out_ps])
   410               (Pretty.block [Pretty.str "Seq.single", Pretty.brk 1, mk_tuple out_ps])
   404               (Pretty.str "Seq.empty"))
   411               (exists (not o is_exhaustive) out_ts'''))
   405           end
   412           end
   406       | compile_prems out_ts vs names gr ps =
   413       | compile_prems out_ts vs names gr ps =
   407           let
   414           let
   408             val vs' = distinct (flat (vs :: map term_vs out_ts));
   415             val vs' = distinct (flat (vs :: map term_vs out_ts));
   409             val Some (p, mode as Some (Mode ((_, js), _))) =
   416             val Some (p, mode as Some (Mode ((_, js), _))) =
   433                    val (gr4, rest) = compile_prems out_ts''' vs' (fst nvs) gr3 ps';
   440                    val (gr4, rest) = compile_prems out_ts''' vs' (fst nvs) gr3 ps';
   434                  in
   441                  in
   435                    (gr4, compile_match (snd nvs) eq_ps out_ps
   442                    (gr4, compile_match (snd nvs) eq_ps out_ps
   436                       (Pretty.block (ps @
   443                       (Pretty.block (ps @
   437                          [Pretty.str " :->", Pretty.brk 1, rest]))
   444                          [Pretty.str " :->", Pretty.brk 1, rest]))
   438                       (Pretty.str "Seq.empty"))
   445                       (exists (not o is_exhaustive) out_ts''))
   439                  end
   446                  end
   440              | Sidecond t =>
   447              | Sidecond t =>
   441                  let
   448                  let
   442                    val (gr2, side_p) = invoke_codegen thy dep true (gr1, t);
   449                    val (gr2, side_p) = invoke_codegen thy dep true (gr1, t);
   443                    val (gr3, rest) = compile_prems [] vs' (fst nvs) gr2 ps';
   450                    val (gr3, rest) = compile_prems [] vs' (fst nvs) gr2 ps';
   444                  in
   451                  in
   445                    (gr3, compile_match (snd nvs) eq_ps out_ps
   452                    (gr3, compile_match (snd nvs) eq_ps out_ps
   446                       (Pretty.block [Pretty.str "?? ", side_p,
   453                       (Pretty.block [Pretty.str "?? ", side_p,
   447                         Pretty.str " :->", Pretty.brk 1, rest])
   454                         Pretty.str " :->", Pretty.brk 1, rest])
   448                       (Pretty.str "Seq.empty"))
   455                       (exists (not o is_exhaustive) out_ts''))
   449                  end)
   456                  end)
   450           end;
   457           end;
   451 
   458 
   452     val (gr', prem_p) = compile_prems in_ts' [] all_vs' gr ps;
   459     val (gr', prem_p) = compile_prems in_ts' [] all_vs' gr ps;
   453   in
   460   in