src/HOL/Tools/Nitpick/nitpick_hol.ML
changeset 42361 23f352990944
parent 41994 c567c860caf6
child 42414 9465651c0db7
equal deleted inserted replaced
42360:da8817d01e7c 42361:23f352990944
   575   Same.commit (Envir.subst_type_same
   575   Same.commit (Envir.subst_type_same
   576                    (Sign.typ_match thy (T1, T1') Vartab.empty)) T2
   576                    (Sign.typ_match thy (T1, T1') Vartab.empty)) T2
   577   handle Type.TYPE_MATCH =>
   577   handle Type.TYPE_MATCH =>
   578          raise TYPE ("Nitpick_HOL.instantiate_type", [T1, T1'], [])
   578          raise TYPE ("Nitpick_HOL.instantiate_type", [T1, T1'], [])
   579 fun varify_and_instantiate_type ctxt T1 T1' T2 =
   579 fun varify_and_instantiate_type ctxt T1 T1' T2 =
   580   let val thy = ProofContext.theory_of ctxt in
   580   let val thy = Proof_Context.theory_of ctxt in
   581     instantiate_type thy (varify_type ctxt T1) T1' (varify_type ctxt T2)
   581     instantiate_type thy (varify_type ctxt T1) T1' (varify_type ctxt T2)
   582   end
   582   end
   583 
   583 
   584 fun repair_constr_type ctxt body_T' T =
   584 fun repair_constr_type ctxt body_T' T =
   585   varify_and_instantiate_type ctxt (body_type T) body_T' T
   585   varify_and_instantiate_type ctxt (body_type T) body_T' T
   637   | is_codatatype _ _ = false
   637   | is_codatatype _ _ = false
   638 fun is_real_quot_type thy (Type (s, _)) =
   638 fun is_real_quot_type thy (Type (s, _)) =
   639     is_some (Quotient_Info.quotdata_lookup_raw thy s)
   639     is_some (Quotient_Info.quotdata_lookup_raw thy s)
   640   | is_real_quot_type _ _ = false
   640   | is_real_quot_type _ _ = false
   641 fun is_quot_type ctxt T =
   641 fun is_quot_type ctxt T =
   642   let val thy = ProofContext.theory_of ctxt in
   642   let val thy = Proof_Context.theory_of ctxt in
   643     is_real_quot_type thy T andalso not (is_codatatype ctxt T)
   643     is_real_quot_type thy T andalso not (is_codatatype ctxt T)
   644   end
   644   end
   645 fun is_pure_typedef ctxt (T as Type (s, _)) =
   645 fun is_pure_typedef ctxt (T as Type (s, _)) =
   646     let val thy = ProofContext.theory_of ctxt in
   646     let val thy = Proof_Context.theory_of ctxt in
   647       is_typedef ctxt s andalso
   647       is_typedef ctxt s andalso
   648       not (is_real_datatype thy s orelse is_real_quot_type thy T orelse
   648       not (is_real_datatype thy s orelse is_real_quot_type thy T orelse
   649            is_codatatype ctxt T orelse is_record_type T orelse
   649            is_codatatype ctxt T orelse is_record_type T orelse
   650            is_integer_like_type T)
   650            is_integer_like_type T)
   651     end
   651     end
   672          | _ => false
   672          | _ => false
   673        end
   673        end
   674      | NONE => false)
   674      | NONE => false)
   675   | is_univ_typedef _ _ = false
   675   | is_univ_typedef _ _ = false
   676 fun is_datatype ctxt stds (T as Type (s, _)) =
   676 fun is_datatype ctxt stds (T as Type (s, _)) =
   677     let val thy = ProofContext.theory_of ctxt in
   677     let val thy = Proof_Context.theory_of ctxt in
   678       (is_typedef ctxt s orelse is_codatatype ctxt T orelse
   678       (is_typedef ctxt s orelse is_codatatype ctxt T orelse
   679        T = @{typ ind} orelse is_real_quot_type thy T) andalso
   679        T = @{typ ind} orelse is_real_quot_type thy T) andalso
   680       not (is_basic_datatype thy stds s)
   680       not (is_basic_datatype thy stds s)
   681     end
   681     end
   682   | is_datatype _ _ _ = false
   682   | is_datatype _ _ _ = false
   763 fun is_constr_like ctxt (s, T) =
   763 fun is_constr_like ctxt (s, T) =
   764   member (op =) [@{const_name FunBox}, @{const_name PairBox},
   764   member (op =) [@{const_name FunBox}, @{const_name PairBox},
   765                  @{const_name Quot}, @{const_name Zero_Rep},
   765                  @{const_name Quot}, @{const_name Zero_Rep},
   766                  @{const_name Suc_Rep}] s orelse
   766                  @{const_name Suc_Rep}] s orelse
   767   let
   767   let
   768     val thy = ProofContext.theory_of ctxt
   768     val thy = Proof_Context.theory_of ctxt
   769     val (x as (_, T)) = (s, unarize_unbox_etc_type T)
   769     val (x as (_, T)) = (s, unarize_unbox_etc_type T)
   770   in
   770   in
   771     is_real_constr thy x orelse is_record_constr x orelse
   771     is_real_constr thy x orelse is_record_constr x orelse
   772     (is_abs_fun ctxt x andalso is_pure_typedef ctxt (range_type T)) orelse
   772     (is_abs_fun ctxt x andalso is_pure_typedef ctxt (range_type T)) orelse
   773     is_coconstr ctxt x
   773     is_coconstr ctxt x
   774   end
   774   end
   775 fun is_stale_constr ctxt (x as (_, T)) =
   775 fun is_stale_constr ctxt (x as (_, T)) =
   776   is_codatatype ctxt (body_type T) andalso is_constr_like ctxt x andalso
   776   is_codatatype ctxt (body_type T) andalso is_constr_like ctxt x andalso
   777   not (is_coconstr ctxt x)
   777   not (is_coconstr ctxt x)
   778 fun is_constr ctxt stds (x as (_, T)) =
   778 fun is_constr ctxt stds (x as (_, T)) =
   779   let val thy = ProofContext.theory_of ctxt in
   779   let val thy = Proof_Context.theory_of ctxt in
   780     is_constr_like ctxt x andalso
   780     is_constr_like ctxt x andalso
   781     not (is_basic_datatype thy stds
   781     not (is_basic_datatype thy stds
   782                          (fst (dest_Type (unarize_type (body_type T))))) andalso
   782                          (fst (dest_Type (unarize_type (body_type T))))) andalso
   783     not (is_stale_constr ctxt x)
   783     not (is_stale_constr ctxt x)
   784   end
   784   end
  1133         val m = fold (Integer.add o num_factors_in_type)
  1133         val m = fold (Integer.add o num_factors_in_type)
  1134                      (List.take (arg_Ts, n)) 0
  1134                      (List.take (arg_Ts, n)) 0
  1135       in Abs ("x", dataT, aux m (nth arg_Ts n) |> snd) end
  1135       in Abs ("x", dataT, aux m (nth arg_Ts n) |> snd) end
  1136   end
  1136   end
  1137 fun select_nth_constr_arg ctxt stds x t n res_T =
  1137 fun select_nth_constr_arg ctxt stds x t n res_T =
  1138   let val thy = ProofContext.theory_of ctxt in
  1138   let val thy = Proof_Context.theory_of ctxt in
  1139     (case strip_comb t of
  1139     (case strip_comb t of
  1140        (Const x', args) =>
  1140        (Const x', args) =>
  1141        if x = x' then nth args n
  1141        if x = x' then nth args n
  1142        else if is_constr_like ctxt x' then Const (@{const_name unknown}, res_T)
  1142        else if is_constr_like ctxt x' then Const (@{const_name unknown}, res_T)
  1143        else raise SAME ()
  1143        else raise SAME ()
  1298       | do_eq _ = false
  1298       | do_eq _ = false
  1299   in do_eq end
  1299   in do_eq end
  1300 
  1300 
  1301 fun all_axioms_of ctxt subst =
  1301 fun all_axioms_of ctxt subst =
  1302   let
  1302   let
  1303     val thy = ProofContext.theory_of ctxt
  1303     val thy = Proof_Context.theory_of ctxt
  1304     val axioms_of_thys =
  1304     val axioms_of_thys =
  1305       maps Thm.axioms_of
  1305       maps Thm.axioms_of
  1306       #> map (apsnd (subst_atomic subst o prop_of))
  1306       #> map (apsnd (subst_atomic subst o prop_of))
  1307       #> filter_out (is_class_axiom o snd)
  1307       #> filter_out (is_class_axiom o snd)
  1308     val specs = Defs.all_specifications_of (Theory.defs_of thy)
  1308     val specs = Defs.all_specifications_of (Theory.defs_of thy)
  1439                     end
  1439                     end
  1440                  | NONE => t)
  1440                  | NONE => t)
  1441                | t => t)
  1441                | t => t)
  1442 
  1442 
  1443 fun case_const_names ctxt stds =
  1443 fun case_const_names ctxt stds =
  1444   let val thy = ProofContext.theory_of ctxt in
  1444   let val thy = Proof_Context.theory_of ctxt in
  1445     Symtab.fold (fn (dtype_s, {index, descr, case_name, ...}) =>
  1445     Symtab.fold (fn (dtype_s, {index, descr, case_name, ...}) =>
  1446                     if is_basic_datatype thy stds dtype_s then
  1446                     if is_basic_datatype thy stds dtype_s then
  1447                       I
  1447                       I
  1448                     else
  1448                     else
  1449                       cons (case_name, AList.lookup (op =) descr index
  1449                       cons (case_name, AList.lookup (op =) descr index
  1887 fun const_choice_spec_table ctxt subst =
  1887 fun const_choice_spec_table ctxt subst =
  1888   map (subst_atomic subst o prop_of) (Nitpick_Choice_Specs.get ctxt)
  1888   map (subst_atomic subst o prop_of) (Nitpick_Choice_Specs.get ctxt)
  1889   |> const_nondef_table
  1889   |> const_nondef_table
  1890 
  1890 
  1891 fun inductive_intro_table ctxt subst def_tables =
  1891 fun inductive_intro_table ctxt subst def_tables =
  1892   let val thy = ProofContext.theory_of ctxt in
  1892   let val thy = Proof_Context.theory_of ctxt in
  1893     def_table_for
  1893     def_table_for
  1894         (maps (map (unfold_mutually_inductive_preds thy def_tables o prop_of)
  1894         (maps (map (unfold_mutually_inductive_preds thy def_tables o prop_of)
  1895                o snd o snd)
  1895                o snd o snd)
  1896          o filter (fn (cat, _) => cat = Spec_Rules.Inductive orelse
  1896          o filter (fn (cat, _) => cat = Spec_Rules.Inductive orelse
  1897                                   cat = Spec_Rules.Co_Inductive)
  1897                                   cat = Spec_Rules.Co_Inductive)
  1920   Unsynchronized.change simp_table
  1920   Unsynchronized.change simp_table
  1921       (Symtab.update (s, eqs @ these (Symtab.lookup (!simp_table) s)))
  1921       (Symtab.update (s, eqs @ these (Symtab.lookup (!simp_table) s)))
  1922 
  1922 
  1923 fun inverse_axioms_for_rep_fun ctxt (x as (_, T)) =
  1923 fun inverse_axioms_for_rep_fun ctxt (x as (_, T)) =
  1924   let
  1924   let
  1925     val thy = ProofContext.theory_of ctxt
  1925     val thy = Proof_Context.theory_of ctxt
  1926     val abs_T = domain_type T
  1926     val abs_T = domain_type T
  1927   in
  1927   in
  1928     typedef_info ctxt (fst (dest_Type abs_T)) |> the
  1928     typedef_info ctxt (fst (dest_Type abs_T)) |> the
  1929     |> pairf #Abs_inverse #Rep_inverse
  1929     |> pairf #Abs_inverse #Rep_inverse
  1930     |> pairself (specialize_type thy x o prop_of o the)
  1930     |> pairself (specialize_type thy x o prop_of o the)
  1931     ||> single |> op ::
  1931     ||> single |> op ::
  1932   end
  1932   end
  1933 fun optimized_typedef_axioms ctxt (abs_z as (abs_s, _)) =
  1933 fun optimized_typedef_axioms ctxt (abs_z as (abs_s, _)) =
  1934   let
  1934   let
  1935     val thy = ProofContext.theory_of ctxt
  1935     val thy = Proof_Context.theory_of ctxt
  1936     val abs_T = Type abs_z
  1936     val abs_T = Type abs_z
  1937   in
  1937   in
  1938     if is_univ_typedef ctxt abs_T then
  1938     if is_univ_typedef ctxt abs_T then
  1939       []
  1939       []
  1940     else case typedef_info ctxt abs_s of
  1940     else case typedef_info ctxt abs_s of
  1955       end
  1955       end
  1956     | NONE => []
  1956     | NONE => []
  1957   end
  1957   end
  1958 fun optimized_quot_type_axioms ctxt stds abs_z =
  1958 fun optimized_quot_type_axioms ctxt stds abs_z =
  1959   let
  1959   let
  1960     val thy = ProofContext.theory_of ctxt
  1960     val thy = Proof_Context.theory_of ctxt
  1961     val abs_T = Type abs_z
  1961     val abs_T = Type abs_z
  1962     val rep_T = rep_type_for_quot_type thy abs_T
  1962     val rep_T = rep_type_for_quot_type thy abs_T
  1963     val (equiv_rel, partial) = equiv_relation_for_quot_type thy abs_T
  1963     val (equiv_rel, partial) = equiv_relation_for_quot_type thy abs_T
  1964     val a_var = Var (("a", 0), abs_T)
  1964     val a_var = Var (("a", 0), abs_T)
  1965     val x_var = Var (("x", 0), rep_T)
  1965     val x_var = Var (("x", 0), rep_T)