src/HOL/Tools/Nitpick/nitpick_scope.ML
changeset 35385 29f81babefd7
parent 35280 54ab4921f826
child 35665 ff2bf50505ab
equal deleted inserted replaced
35384:88dbcfe75c45 35385:29f81babefd7
    21   type dtype_spec = {
    21   type dtype_spec = {
    22     typ: typ,
    22     typ: typ,
    23     card: int,
    23     card: int,
    24     co: bool,
    24     co: bool,
    25     standard: bool,
    25     standard: bool,
    26     complete: bool,
    26     complete: bool * bool,
    27     concrete: bool,
    27     concrete: bool * bool,
    28     deep: bool,
    28     deep: bool,
    29     constrs: constr_spec list}
    29     constrs: constr_spec list}
    30 
    30 
    31   type scope = {
    31   type scope = {
    32     hol_ctxt: hol_context,
    32     hol_ctxt: hol_context,
    37     datatypes: dtype_spec list,
    37     datatypes: dtype_spec list,
    38     ofs: int Typtab.table}
    38     ofs: int Typtab.table}
    39 
    39 
    40   val datatype_spec : dtype_spec list -> typ -> dtype_spec option
    40   val datatype_spec : dtype_spec list -> typ -> dtype_spec option
    41   val constr_spec : dtype_spec list -> styp -> constr_spec
    41   val constr_spec : dtype_spec list -> styp -> constr_spec
    42   val is_complete_type : dtype_spec list -> typ -> bool
    42   val is_complete_type : dtype_spec list -> bool -> typ -> bool
    43   val is_concrete_type : dtype_spec list -> typ -> bool
    43   val is_concrete_type : dtype_spec list -> bool -> typ -> bool
    44   val is_exact_type : dtype_spec list -> typ -> bool
    44   val is_exact_type : dtype_spec list -> bool -> typ -> bool
    45   val offset_of_type : int Typtab.table -> typ -> int
    45   val offset_of_type : int Typtab.table -> typ -> int
    46   val spec_of_type : scope -> typ -> int * int
    46   val spec_of_type : scope -> typ -> int * int
    47   val pretties_for_scope : scope -> bool -> Pretty.T list
    47   val pretties_for_scope : scope -> bool -> Pretty.T list
    48   val multiline_string_for_scope : scope -> string
    48   val multiline_string_for_scope : scope -> string
    49   val scopes_equivalent : scope -> scope -> bool
    49   val scopes_equivalent : scope -> scope -> bool
    50   val scope_less_eq : scope -> scope -> bool
    50   val scope_less_eq : scope -> scope -> bool
    51   val all_scopes :
    51   val all_scopes :
    52     hol_context -> bool -> int -> (typ option * int list) list
    52     hol_context -> bool -> int -> (typ option * int list) list
    53     -> (styp option * int list) list -> (styp option * int list) list
    53     -> (styp option * int list) list -> (styp option * int list) list
    54     -> int list -> int list -> typ list -> typ list -> typ list
    54     -> int list -> int list -> typ list -> typ list -> typ list -> typ list
    55     -> int * scope list
    55     -> int * scope list
    56 end;
    56 end;
    57 
    57 
    58 structure Nitpick_Scope : NITPICK_SCOPE =
    58 structure Nitpick_Scope : NITPICK_SCOPE =
    59 struct
    59 struct
    72 type dtype_spec = {
    72 type dtype_spec = {
    73   typ: typ,
    73   typ: typ,
    74   card: int,
    74   card: int,
    75   co: bool,
    75   co: bool,
    76   standard: bool,
    76   standard: bool,
    77   complete: bool,
    77   complete: bool * bool,
    78   concrete: bool,
    78   concrete: bool * bool,
    79   deep: bool,
    79   deep: bool,
    80   constrs: constr_spec list}
    80   constrs: constr_spec list}
    81 
    81 
    82 type scope = {
    82 type scope = {
    83   hol_ctxt: hol_context,
    83   hol_ctxt: hol_context,
   103     case List.find (curry (op =) (s, body_type T) o (apsnd body_type o #const))
   103     case List.find (curry (op =) (s, body_type T) o (apsnd body_type o #const))
   104                    constrs of
   104                    constrs of
   105       SOME c => c
   105       SOME c => c
   106     | NONE => constr_spec dtypes x
   106     | NONE => constr_spec dtypes x
   107 
   107 
   108 (* dtype_spec list -> typ -> bool *)
   108 (* dtype_spec list -> bool -> typ -> bool *)
   109 fun is_complete_type dtypes (Type ("fun", [T1, T2])) =
   109 fun is_complete_type dtypes facto (Type ("fun", [T1, T2])) =
   110     is_concrete_type dtypes T1 andalso is_complete_type dtypes T2
   110     is_concrete_type dtypes facto T1 andalso is_complete_type dtypes facto T2
   111   | is_complete_type dtypes (Type ("*", Ts)) =
   111   | is_complete_type dtypes facto (Type ("*", Ts)) =
   112     forall (is_complete_type dtypes) Ts
   112     forall (is_complete_type dtypes facto) Ts
   113   | is_complete_type dtypes T =
   113   | is_complete_type dtypes facto T =
   114     not (is_integer_like_type T) andalso not (is_bit_type T) andalso
   114     not (is_integer_like_type T) andalso not (is_bit_type T) andalso
   115     #complete (the (datatype_spec dtypes T))
   115     fun_from_pair (#complete (the (datatype_spec dtypes T))) facto
   116     handle Option.Option => true
   116     handle Option.Option => true
   117 and is_concrete_type dtypes (Type ("fun", [T1, T2])) =
   117 and is_concrete_type dtypes facto (Type ("fun", [T1, T2])) =
   118     is_complete_type dtypes T1 andalso is_concrete_type dtypes T2
   118     is_complete_type dtypes facto T1 andalso is_concrete_type dtypes facto T2
   119   | is_concrete_type dtypes (Type ("*", Ts)) =
   119   | is_concrete_type dtypes facto (Type ("*", Ts)) =
   120     forall (is_concrete_type dtypes) Ts
   120     forall (is_concrete_type dtypes facto) Ts
   121   | is_concrete_type dtypes T =
   121   | is_concrete_type dtypes facto T =
   122     #concrete (the (datatype_spec dtypes T)) handle Option.Option => true
   122     fun_from_pair (#concrete (the (datatype_spec dtypes T))) facto
   123 fun is_exact_type dtypes = is_complete_type dtypes andf is_concrete_type dtypes
   123     handle Option.Option => true
       
   124 fun is_exact_type dtypes facto =
       
   125   is_complete_type dtypes facto andf is_concrete_type dtypes facto
   124 
   126 
   125 (* int Typtab.table -> typ -> int *)
   127 (* int Typtab.table -> typ -> int *)
   126 fun offset_of_type ofs T =
   128 fun offset_of_type ofs T =
   127   case Typtab.lookup ofs T of
   129   case Typtab.lookup ofs T of
   128     SOME j0 => j0
   130     SOME j0 => j0
   459   in
   461   in
   460     {const = x, delta = delta, epsilon = epsilon, exclusive = exclusive,
   462     {const = x, delta = delta, epsilon = epsilon, exclusive = exclusive,
   461      explicit_max = max, total = total} :: constrs
   463      explicit_max = max, total = total} :: constrs
   462   end
   464   end
   463 
   465 
   464 (* hol_context -> (typ * int) list -> typ -> bool *)
   466 (* hol_context -> bool -> typ list -> (typ * int) list -> typ -> bool *)
   465 fun has_exact_card hol_ctxt card_assigns T =
   467 fun has_exact_card hol_ctxt facto finitizable_dataTs card_assigns T =
   466   let val card = card_of_type card_assigns T in
   468   let val card = card_of_type card_assigns T in
   467     card = bounded_exact_card_of_type hol_ctxt (card + 1) 0 card_assigns T
   469     card = bounded_exact_card_of_type hol_ctxt
   468   end
   470                (if facto then finitizable_dataTs else []) (card + 1) 0
   469 
   471                card_assigns T
   470 (* hol_context -> bool -> typ list -> scope_desc -> typ * int -> dtype_spec *)
   472   end
       
   473 
       
   474 (* hol_context -> bool -> typ list -> typ list -> scope_desc -> typ * int
       
   475    -> dtype_spec *)
   471 fun datatype_spec_from_scope_descriptor (hol_ctxt as {thy, stds, ...}) binarize
   476 fun datatype_spec_from_scope_descriptor (hol_ctxt as {thy, stds, ...}) binarize
   472         deep_dataTs (desc as (card_assigns, _)) (T, card) =
   477         deep_dataTs finitizable_dataTs (desc as (card_assigns, _)) (T, card) =
   473   let
   478   let
   474     val deep = member (op =) deep_dataTs T
   479     val deep = member (op =) deep_dataTs T
   475     val co = is_codatatype thy T
   480     val co = is_codatatype thy T
   476     val standard = is_standard_datatype thy stds T
   481     val standard = is_standard_datatype thy stds T
   477     val xs = binarized_and_boxed_datatype_constrs hol_ctxt binarize T
   482     val xs = binarized_and_boxed_datatype_constrs hol_ctxt binarize T
   478     val self_recs = map (is_self_recursive_constr_type o snd) xs
   483     val self_recs = map (is_self_recursive_constr_type o snd) xs
   479     val (num_self_recs, num_non_self_recs) =
   484     val (num_self_recs, num_non_self_recs) =
   480       List.partition I self_recs |> pairself length
   485       List.partition I self_recs |> pairself length
   481     val complete = has_exact_card hol_ctxt card_assigns T
   486     (* bool -> bool *)
   482     val concrete = is_word_type T orelse
   487     fun is_complete facto =
   483                    (xs |> maps (binder_types o snd) |> maps binder_types
   488       has_exact_card hol_ctxt facto finitizable_dataTs card_assigns T
   484                        |> forall (has_exact_card hol_ctxt card_assigns))
   489     fun is_concrete facto =
       
   490       is_word_type T orelse
       
   491       xs |> maps (binder_types o snd) |> maps binder_types
       
   492          |> forall (has_exact_card hol_ctxt facto finitizable_dataTs
       
   493                                    card_assigns)
       
   494     val complete = pair_from_fun is_complete
       
   495     val concrete = pair_from_fun is_concrete
   485     (* int -> int *)
   496     (* int -> int *)
   486     fun sum_dom_cards max =
   497     fun sum_dom_cards max =
   487       map (domain_card max card_assigns o snd) xs |> Integer.sum
   498       map (domain_card max card_assigns o snd) xs |> Integer.sum
   488     val constrs =
   499     val constrs =
   489       fold_rev (add_constr_spec desc co card sum_dom_cards num_self_recs
   500       fold_rev (add_constr_spec desc co card sum_dom_cards num_self_recs
   492   in
   503   in
   493     {typ = T, card = card, co = co, standard = standard, complete = complete,
   504     {typ = T, card = card, co = co, standard = standard, complete = complete,
   494      concrete = concrete, deep = deep, constrs = constrs}
   505      concrete = concrete, deep = deep, constrs = constrs}
   495   end
   506   end
   496 
   507 
   497 (* hol_context -> bool -> int -> typ list -> scope_desc -> scope *)
   508 (* hol_context -> bool -> int -> typ list -> typ list -> scope_desc -> scope *)
   498 fun scope_from_descriptor (hol_ctxt as {thy, stds, ...}) binarize sym_break
   509 fun scope_from_descriptor (hol_ctxt as {thy, stds, ...}) binarize sym_break
   499                           deep_dataTs (desc as (card_assigns, _)) =
   510                           deep_dataTs finitizable_dataTs
       
   511                           (desc as (card_assigns, _)) =
   500   let
   512   let
   501     val datatypes =
   513     val datatypes =
   502       map (datatype_spec_from_scope_descriptor hol_ctxt binarize deep_dataTs
   514       map (datatype_spec_from_scope_descriptor hol_ctxt binarize deep_dataTs
   503                desc) (filter (is_datatype thy stds o fst) card_assigns)
   515                                                finitizable_dataTs desc)
       
   516           (filter (is_datatype thy stds o fst) card_assigns)
   504     val bits = card_of_type card_assigns @{typ signed_bit} - 1
   517     val bits = card_of_type card_assigns @{typ signed_bit} - 1
   505                handle TYPE ("Nitpick_HOL.card_of_type", _, _) =>
   518                handle TYPE ("Nitpick_HOL.card_of_type", _, _) =>
   506                       card_of_type card_assigns @{typ unsigned_bit}
   519                       card_of_type card_assigns @{typ unsigned_bit}
   507                       handle TYPE ("Nitpick_HOL.card_of_type", _, _) => 0
   520                       handle TYPE ("Nitpick_HOL.card_of_type", _, _) => 0
   508     val bisim_depth = card_of_type card_assigns @{typ bisim_iterator} - 1
   521     val bisim_depth = card_of_type card_assigns @{typ bisim_iterator} - 1
   528 val max_scopes = 4096
   541 val max_scopes = 4096
   529 val distinct_threshold = 512
   542 val distinct_threshold = 512
   530 
   543 
   531 (* hol_context -> bool -> int -> (typ option * int list) list
   544 (* hol_context -> bool -> int -> (typ option * int list) list
   532    -> (styp option * int list) list -> (styp option * int list) list -> int list
   545    -> (styp option * int list) list -> (styp option * int list) list -> int list
   533    -> typ list -> typ list -> typ list -> int * scope list *)
   546    -> typ list -> typ list -> typ list ->typ list -> int * scope list *)
   534 fun all_scopes (hol_ctxt as {thy, ...}) binarize sym_break cards_assigns
   547 fun all_scopes (hol_ctxt as {thy, ...}) binarize sym_break cards_assigns
   535                maxes_assigns iters_assigns bitss bisim_depths mono_Ts nonmono_Ts
   548                maxes_assigns iters_assigns bitss bisim_depths mono_Ts nonmono_Ts
   536                deep_dataTs =
   549                deep_dataTs finitizable_dataTs =
   537   let
   550   let
   538     val cards_assigns = repair_cards_assigns_wrt_boxing thy mono_Ts
   551     val cards_assigns = repair_cards_assigns_wrt_boxing thy mono_Ts
   539                                                         cards_assigns
   552                                                         cards_assigns
   540     val blocks = blocks_for_types hol_ctxt binarize cards_assigns maxes_assigns
   553     val blocks = blocks_for_types hol_ctxt binarize cards_assigns maxes_assigns
   541                                   iters_assigns bitss bisim_depths mono_Ts
   554                                   iters_assigns bitss bisim_depths mono_Ts
   548                  head
   561                  head
   549   in
   562   in
   550     (length all - length head,
   563     (length all - length head,
   551      descs |> length descs <= distinct_threshold ? distinct (op =)
   564      descs |> length descs <= distinct_threshold ? distinct (op =)
   552            |> map (scope_from_descriptor hol_ctxt binarize sym_break
   565            |> map (scope_from_descriptor hol_ctxt binarize sym_break
   553                                          deep_dataTs))
   566                                          deep_dataTs finitizable_dataTs))
   554   end
   567   end
   555 
   568 
   556 end;
   569 end;