src/HOL/Tools/Nitpick/nitpick_model.ML
changeset 34121 5e831d805118
parent 33982 1ae222745c4a
child 34123 c4988215a691
equal deleted inserted replaced
34120:f9920a3ddf50 34121:5e831d805118
    58   nat_subscript (j + 1)
    58   nat_subscript (j + 1)
    59   |> (s <> "" andalso Symbol.is_ascii_digit (List.last (explode s)))
    59   |> (s <> "" andalso Symbol.is_ascii_digit (List.last (explode s)))
    60      ? prefix "\<^isub>,"
    60      ? prefix "\<^isub>,"
    61 (* string -> typ -> int -> string *)
    61 (* string -> typ -> int -> string *)
    62 fun atom_name prefix (T as Type (s, _)) j =
    62 fun atom_name prefix (T as Type (s, _)) j =
    63     prefix ^ substring (short_name s, 0, 1) ^ atom_suffix s j
    63     prefix ^ substring (shortest_name s, 0, 1) ^ atom_suffix s j
    64   | atom_name prefix (T as TFree (s, _)) j =
    64   | atom_name prefix (T as TFree (s, _)) j =
    65     prefix ^ perhaps (try (unprefix "'")) s ^ atom_suffix s j
    65     prefix ^ perhaps (try (unprefix "'")) s ^ atom_suffix s j
    66   | atom_name _ T _ = raise TYPE ("Nitpick_Model.atom_name", [T], [])
    66   | atom_name _ T _ = raise TYPE ("Nitpick_Model.atom_name", [T], [])
    67 (* bool -> typ -> int -> term *)
    67 (* bool -> typ -> int -> term *)
    68 fun atom for_auto T j =
    68 fun atom for_auto T j =
   123       | aux T1 T2 ((t1, t2) :: ps) =
   123       | aux T1 T2 ((t1, t2) :: ps) =
   124         Const (@{const_name fun_upd}, [T1 --> T2, T1, T2] ---> T1 --> T2)
   124         Const (@{const_name fun_upd}, [T1 --> T2, T1, T2] ---> T1 --> T2)
   125         $ aux T1 T2 ps $ t1 $ t2
   125         $ aux T1 T2 ps $ t1 $ t2
   126   in aux T1 T2 o rev end
   126   in aux T1 T2 o rev end
   127 (* term -> bool *)
   127 (* term -> bool *)
   128 fun is_plain_fun (Const (s, _)) = s mem [@{const_name undefined}, non_opt_name]
   128 fun is_plain_fun (Const (s, _)) =
       
   129     (s = @{const_name undefined} orelse s = non_opt_name)
   129   | is_plain_fun (Const (@{const_name fun_upd}, _) $ t0 $ _ $ _) =
   130   | is_plain_fun (Const (@{const_name fun_upd}, _) $ t0 $ _ $ _) =
   130     is_plain_fun t0
   131     is_plain_fun t0
   131   | is_plain_fun _ = false
   132   | is_plain_fun _ = false
   132 (* term -> bool * (term list * term list) *)
   133 (* term -> bool * (term list * term list) *)
   133 val dest_plain_fun =
   134 val dest_plain_fun =
   348             val discr_jsss = map (tuples_for_const o discr_for_constr o #const)
   349             val discr_jsss = map (tuples_for_const o discr_for_constr o #const)
   349                                  constrs
   350                                  constrs
   350             val real_j = j + offset_of_type ofs T
   351             val real_j = j + offset_of_type ofs T
   351             val constr_x as (constr_s, constr_T) =
   352             val constr_x as (constr_s, constr_T) =
   352               get_first (fn (jss, {const, ...}) =>
   353               get_first (fn (jss, {const, ...}) =>
   353                             if [real_j] mem jss then SOME const else NONE)
   354                             if member (op =) jss [real_j] then SOME const
       
   355                             else NONE)
   354                         (discr_jsss ~~ constrs) |> the
   356                         (discr_jsss ~~ constrs) |> the
   355             val arg_Ts = curried_binder_types constr_T
   357             val arg_Ts = curried_binder_types constr_T
   356             val sel_xs = map (boxed_nth_sel_for_constr ext_ctxt constr_x)
   358             val sel_xs = map (boxed_nth_sel_for_constr ext_ctxt constr_x)
   357                              (index_seq 0 (length arg_Ts))
   359                              (index_seq 0 (length arg_Ts))
   358             val sel_Rs =
   360             val sel_Rs =
   367             val arg_jsss =
   369             val arg_jsss =
   368               map (map_filter (fn js => if hd js = real_j then SOME (tl js)
   370               map (map_filter (fn js => if hd js = real_j then SOME (tl js)
   369                                         else NONE)) sel_jsss
   371                                         else NONE)) sel_jsss
   370             val uncur_arg_Ts = binder_types constr_T
   372             val uncur_arg_Ts = binder_types constr_T
   371           in
   373           in
   372             if co andalso (T, j) mem seen then
   374             if co andalso member (op =) seen (T, j) then
   373               Var (var ())
   375               Var (var ())
   374             else
   376             else
   375               let
   377               let
   376                 val seen = seen |> co ? cons (T, j)
   378                 val seen = seen |> co ? cons (T, j)
   377                 val ts =
   379                 val ts =
   406                   else
   408                   else
   407                     list_comb (Const constr_x, ts)
   409                     list_comb (Const constr_x, ts)
   408               in
   410               in
   409                 if co then
   411                 if co then
   410                   let val var = var () in
   412                   let val var = var () in
   411                     if exists_subterm (equal (Var var)) t then
   413                     if exists_subterm (curry (op =) (Var var)) t then
   412                       Const (@{const_name The}, (T --> bool_T) --> T)
   414                       Const (@{const_name The}, (T --> bool_T) --> T)
   413                       $ Abs ("\<omega>", T,
   415                       $ Abs ("\<omega>", T,
   414                              Const (@{const_name "op ="}, [T, T] ---> bool_T)
   416                              Const (@{const_name "op ="}, [T, T] ---> bool_T)
   415                              $ Bound 0 $ abstract_over (Var var, t))
   417                              $ Bound 0 $ abstract_over (Var var, t))
   416                     else
   418                     else
   447         let
   449         let
   448           val jss1 = all_combinations_for_rep R1
   450           val jss1 = all_combinations_for_rep R1
   449           val ts1 = map (term_for_rep seen T1 T1 R1 o single) jss1
   451           val ts1 = map (term_for_rep seen T1 T1 R1 o single) jss1
   450           val ts2 =
   452           val ts2 =
   451             map (fn js => term_for_rep seen T2 T2 (Atom (2, 0))
   453             map (fn js => term_for_rep seen T2 T2 (Atom (2, 0))
   452                                        [[int_for_bool (js mem jss)]]) jss1
   454                                        [[int_for_bool (member (op =) jss js)]])
       
   455                 jss1
   453         in make_fun false T1 T2 T' ts1 ts2 end
   456         in make_fun false T1 T2 T' ts1 ts2 end
   454       | term_for_rep seen (Type ("fun", [T1, T2])) T' (Func (R1, R2)) jss =
   457       | term_for_rep seen (Type ("fun", [T1, T2])) T' (Func (R1, R2)) jss =
   455         let
   458         let
   456           val arity1 = arity_of_rep R1
   459           val arity1 = arity_of_rep R1
   457           val jss1 = all_combinations_for_rep R1
   460           val jss1 = all_combinations_for_rep R1
   515     let val T = fastype_of t1 in
   518     let val T = fastype_of t1 in
   516       if exists_subtype (member (op =) coTs) T then
   519       if exists_subtype (member (op =) coTs) T then
   517         let
   520         let
   518           val ((head1, args1), (head2, args2)) =
   521           val ((head1, args1), (head2, args2)) =
   519             pairself (strip_comb o unfold_outer_the_binders) (t1, t2)
   522             pairself (strip_comb o unfold_outer_the_binders) (t1, t2)
   520           val max_depth = max_depth - (if T mem coTs then 1 else 0)
   523           val max_depth = max_depth - (if member (op =) coTs T then 1 else 0)
   521         in
   524         in
   522           head1 = head2
   525           head1 = head2
   523           andalso forall (bisimilar_values coTs max_depth) (args1 ~~ args2)
   526           andalso forall (bisimilar_values coTs max_depth) (args1 ~~ args2)
   524         end
   527         end
   525       else
   528       else
   637     val (skolem_names, nonskolem_nonsel_names) =
   640     val (skolem_names, nonskolem_nonsel_names) =
   638       List.partition is_skolem_name nonsel_names
   641       List.partition is_skolem_name nonsel_names
   639     val (eval_names, noneval_nonskolem_nonsel_names) =
   642     val (eval_names, noneval_nonskolem_nonsel_names) =
   640       List.partition (String.isPrefix eval_prefix o nickname_of)
   643       List.partition (String.isPrefix eval_prefix o nickname_of)
   641                      nonskolem_nonsel_names
   644                      nonskolem_nonsel_names
   642       ||> filter_out (equal @{const_name bisim_iterator_max} o nickname_of)
   645       ||> filter_out (curry (op =) @{const_name bisim_iterator_max}
       
   646                       o nickname_of)
   643     val free_names =
   647     val free_names =
   644       map (fn x as (s, T) =>
   648       map (fn x as (s, T) =>
   645               case filter (equal x o pairf nickname_of (unbox_type o type_of))
   649               case filter (curry (op =) x
       
   650                            o pairf nickname_of (unbox_type o type_of))
   646                           free_names of
   651                           free_names of
   647                 [name] => name
   652                 [name] => name
   648               | [] => FreeName (s, T, Any)
   653               | [] => FreeName (s, T, Any)
   649               | _ => raise TERM ("Nitpick_Model.reconstruct_hol_model",
   654               | _ => raise TERM ("Nitpick_Model.reconstruct_hol_model",
   650                                  [Const x])) all_frees
   655                                  [Const x])) all_frees