src/Pure/more_thm.ML
changeset 81958 87cc86357dc2
parent 81956 658f3237eadd
child 81959 fae61f1c8113
--- a/src/Pure/more_thm.ML	Thu Jan 23 14:25:31 2025 +0100
+++ b/src/Pure/more_thm.ML	Thu Jan 23 20:06:14 2025 +0100
@@ -408,19 +408,43 @@
   if TFrees.is_empty instT andalso Frees.is_empty inst then th
   else
     let
-      val tfrees = Names.build (TFrees.fold (Names.add_set o #1 o #1) instT);
-      val frees = Names.build (Frees.fold (Names.add_set o #1 o #1) inst);
+      val namesT = Names.build (TFrees.fold (Names.add_set o #1 o #1) instT);
+      val names = Names.build (Frees.fold (Names.add_set o #1 o #1) inst);
+
+      val idx =
+        (Thm.maxidx_of th
+          |> TFrees.fold (Integer.max o Thm.maxidx_of_ctyp o #2) instT
+          |> Frees.fold (Integer.max o Thm.maxidx_of_cterm o #2) inst) + 1;
+      fun index ((a, A), b) = (((a, idx), A), b);
 
-      val idx = Thm.maxidx_of th + 1;
-      fun index ((a, A), b) = (((a, idx), A), b);
-      val instT' = TVars.build (TFrees.fold (TVars.add o index) instT);
-      val inst' = Vars.build (Frees.fold (Vars.add o index) inst);
+      val instT' =
+        TVars.build (TFrees.fold (TVars.add o index) instT)
+        |> not (Names.is_empty namesT) ? Thm.fold_atomic_ctyps {hyps = true}
+            (fn TFree (a, S) => Names.defined namesT a andalso not (TFrees.defined instT (a, S))
+              | _ => false)
+            (fn cT =>
+              let val (a, S) = dest_TFree (Thm.typ_of cT)
+              in TVars.add (((a, idx), S), cT) end) th;
+
+      val inst_typ = Term_Subst.instantiateT_frees (TFrees.map (K Thm.typ_of) instT);
+      val inst_ctyp =
+        Thm.generalize_cterm (namesT, Names.empty) idx #>
+        Thm.instantiate_cterm (instT', Vars.empty);
+
+      val inst' =
+        Vars.build (Frees.fold (Vars.add o index) inst)
+        |> not (Names.is_empty names) ? Thm.fold_atomic_cterms {hyps = true}
+            (fn Free (x, T) => Names.defined names x andalso not (Frees.defined inst (x, inst_typ T))
+              | _ => false)
+            (fn ct =>
+              let val (x, T) = dest_Free (Thm.term_of ct)
+              in Vars.add (((x, idx), inst_typ T), inst_ctyp ct) end) th;
 
       val hyps = Thm.chyps_of th;
     in
       th
       |> fold_rev Thm.implies_intr hyps
-      |> Thm.generalize (tfrees, frees) idx
+      |> Thm.generalize (namesT, names) idx
       |> Thm.instantiate (instT', inst')
       |> assume_prems (length hyps)
     end;