src/Pure/Proof/reconstruct.ML
changeset 13669 a9f229eafba7
parent 13610 d4a2ac255447
child 13715 61bfaa892a41
--- a/src/Pure/Proof/reconstruct.ML	Mon Oct 21 17:17:40 2002 +0200
+++ b/src/Pure/Proof/reconstruct.ML	Mon Oct 21 17:19:51 2002 +0200
@@ -47,13 +47,8 @@
                  iTs=Vartab.merge (op =) (iTs1, iTs2),
                  maxidx=Int.max (maxidx1, maxidx2)};
 
-fun strip_abs (_::Ts) (Abs (_, _, t)) = strip_abs Ts t
-  | strip_abs _ t = t;
 
-
-(********************************************************************************
-  generate constraints for proof term
-*********************************************************************************)
+(**** generate constraints for proof term ****)
 
 fun mk_var env Ts T = 
   let val (env', v) = Envir.genvar "a" (env, rev Ts ---> T)
@@ -65,38 +60,6 @@
 
 fun mk_abs Ts t = foldl (fn (u, T) => Abs ("", T, u)) (t, Ts);
 
-fun make_Tconstraints_cprf maxidx cprf =
-  let
-    fun mk_Tcnstrts maxidx Ts (Abst (s, Some T, cprf)) =
-          let val (cs, cprf', maxidx') = mk_Tcnstrts maxidx (T::Ts) cprf;
-          in (cs, Abst (s, Some T, cprf'), maxidx') end
-      | mk_Tcnstrts maxidx Ts (Abst (s, None, cprf)) =
-          let
-            val T' = TVar (("'t", maxidx+1), ["logic"]);
-            val (cs, cprf', maxidx') = mk_Tcnstrts (maxidx+1) (T'::Ts) cprf;
-          in (cs, Abst (s, Some T', cprf'), maxidx') end
-      | mk_Tcnstrts maxidx Ts (AbsP (s, Some t, cprf)) =
-          let val (cs, cprf', maxidx') = mk_Tcnstrts maxidx Ts cprf;
-          in ((mk_abs Ts t, rev Ts ---> propT)::cs, AbsP (s, Some t, cprf'), maxidx') end
-      | mk_Tcnstrts maxidx Ts (AbsP (s, None, cprf)) =
-          let val (cs, cprf', maxidx') = mk_Tcnstrts maxidx Ts cprf;
-          in (cs, AbsP (s, None, cprf'), maxidx') end
-      | mk_Tcnstrts maxidx Ts (cprf1 %% cprf2) =
-          let
-            val (cs, cprf1', maxidx') = mk_Tcnstrts maxidx Ts cprf1;
-            val (cs', cprf2', maxidx'') = mk_Tcnstrts maxidx' Ts cprf2;
-          in (cs' @ cs, cprf1' %% cprf2', maxidx'') end
-      | mk_Tcnstrts maxidx Ts (cprf % Some t) =
-          let val (cs, cprf', maxidx') = mk_Tcnstrts maxidx Ts cprf;
-          in ((mk_abs Ts t, rev Ts ---> TypeInfer.logicT)::cs,
-            cprf' % Some t, maxidx')
-          end
-      | mk_Tcnstrts maxidx Ts (cprf % None) =
-          let val (cs, cprf', maxidx') = mk_Tcnstrts maxidx Ts cprf;
-          in (cs, cprf % None, maxidx') end
-      | mk_Tcnstrts maxidx _ cprf = ([], cprf, maxidx);
-  in mk_Tcnstrts maxidx [] cprf end;
-
 fun unifyT sg env T U =
   let
     val Envir.Envir {asol, iTs, maxidx} = env;
@@ -105,6 +68,44 @@
   handle Type.TUNIFY => error ("Non-unifiable types:\n" ^
     Sign.string_of_typ sg T ^ "\n\n" ^ Sign.string_of_typ sg U);
 
+fun chaseT (env as Envir.Envir {iTs, ...}) (T as TVar (ixn, _)) =
+      (case Vartab.lookup (iTs, ixn) of None => T | Some T' => chaseT env T')
+  | chaseT _ T = T;
+
+fun infer_type sg (env as Envir.Envir {maxidx, asol, iTs}) Ts vTs
+      (t as Const (s, T)) = if T = dummyT then (case Sign.const_type sg s of
+          None => error ("reconstruct_proof: No such constant: " ^ quote s)
+        | Some T => 
+            let val T' = incr_tvar (maxidx + 1) T
+            in (Const (s, T'), T', vTs,
+              Envir.Envir {maxidx = maxidx + 1, asol = asol, iTs = iTs})
+            end)
+      else (t, T, vTs, env)
+  | infer_type sg env Ts vTs (t as Free (s, T)) =
+      if T = dummyT then (case Symtab.lookup (vTs, s) of
+          None =>
+            let val (env', T) = mk_tvar (env, [])
+            in (Free (s, T), T, Symtab.update_new ((s, T), vTs), env') end
+        | Some T => (Free (s, T), T, vTs, env))
+      else (t, T, vTs, env)
+  | infer_type sg env Ts vTs (Var _) = error "reconstruct_proof: internal error"
+  | infer_type sg env Ts vTs (Abs (s, T, t)) =
+      let
+        val (env', T') = if T = dummyT then mk_tvar (env, []) else (env, T);
+        val (t', U, vTs', env'') = infer_type sg env' (T' :: Ts) vTs t
+      in (Abs (s, T', t'), T' --> U, vTs', env'') end
+  | infer_type sg env Ts vTs (t $ u) =
+      let
+        val (t', T, vTs1, env1) = infer_type sg env Ts vTs t;
+        val (u', U, vTs2, env2) = infer_type sg env1 Ts vTs1 u;
+      in (case chaseT env2 T of
+          Type ("fun", [U', V]) => (t' $ u', V, vTs2, unifyT sg env2 U U')
+        | _ =>
+          let val (env3, V) = mk_tvar (env2, [])
+          in (t' $ u', V, vTs2, unifyT sg env3 T (U --> V)) end)
+      end
+  | infer_type sg env Ts vTs (t as Bound i) = (t, nth_elem (i, Ts), vTs, env);
+
 fun decompose sg env Ts t u = case (Envir.head_norm env t, Envir.head_norm env u) of
     (Const ("all", _) $ t, Const ("all", _) $ u) => decompose sg env Ts t u
   | (Const ("==>", _) $ t1 $ t2, Const ("==>", _) $ u1 $ u2) =>
@@ -117,104 +118,112 @@
 fun cantunify sg t u = error ("Non-unifiable terms:\n" ^
   Sign.string_of_term sg t ^ "\n\n" ^ Sign.string_of_term sg u);
 
-fun make_constraints_cprf sg env ts cprf =
+fun make_constraints_cprf sg env cprf =
   let
-    fun add_cnstrt Ts prop prf cs env ts (t, u) =
+    fun add_cnstrt Ts prop prf cs env vTs (t, u) =
       let
         val t' = mk_abs Ts t;
         val u' = mk_abs Ts u
       in
-        (prop, prf, cs, Pattern.unify (sg, env, [(t', u')]), ts)
+        (prop, prf, cs, Pattern.unify (sg, env, [(t', u')]), vTs)
         handle Pattern.Pattern =>
             let val (env', cs') = decompose sg env [] t' u'
-            in (prop, prf, cs @ cs', env', ts) end
+            in (prop, prf, cs @ cs', env', vTs) end
         | Pattern.Unif =>
             cantunify sg (Envir.norm_term env t') (Envir.norm_term env u')
       end;
 
-    fun mk_cnstrts_atom env ts prop opTs prf =
+    fun mk_cnstrts_atom env vTs prop opTs prf =
           let
             val tvars = term_tvars prop;
-            val (env', Ts) = if_none (apsome (pair env) opTs)
-              (foldl_map (mk_tvar o apsnd snd) (env, tvars));
-            val prop' = subst_TVars (map fst tvars ~~ Ts) (forall_intr_vfs prop)
-              handle LIST _ => error ("Wrong number of type arguments for " ^
-                quote (fst (get_name_tags [] prop prf)))
-          in (prop', change_type (Some Ts) prf, [], env', ts) end;
+            val tfrees = term_tfrees prop;
+            val (prop', fmap) = Type.varify (prop, []);
+            val (env', Ts) = (case opTs of
+                None => foldl_map mk_tvar (env, map snd tvars @ map snd tfrees)
+              | Some Ts => (env, Ts));
+            val prop'' = subst_TVars (map fst tvars @ map snd fmap ~~ Ts)
+              (forall_intr_vfs prop') handle LIST _ =>
+                error ("Wrong number of type arguments for " ^
+                  quote (fst (get_name_tags [] prop prf)))
+          in (prop'', change_type (Some Ts) prf, [], env', vTs) end;
 
-    fun mk_cnstrts env _ Hs ts (PBound i) = (nth_elem (i, Hs), PBound i, [], env, ts)
-      | mk_cnstrts env Ts Hs ts (Abst (s, Some T, cprf)) =
-          let val (t, prf, cnstrts, env', ts') =
-              mk_cnstrts env (T::Ts) (map (incr_boundvars 1) Hs) ts cprf;
+    fun head_norm (prop, prf, cnstrts, env, vTs) =
+      (Envir.head_norm env prop, prf, cnstrts, env, vTs);
+ 
+    fun mk_cnstrts env _ Hs vTs (PBound i) = (nth_elem (i, Hs), PBound i, [], env, vTs)
+      | mk_cnstrts env Ts Hs vTs (Abst (s, opT, cprf)) =
+          let
+            val (env', T) = (case opT of
+              None => mk_tvar (env, logicS) | Some T => (env, T));
+            val (t, prf, cnstrts, env'', vTs') =
+              mk_cnstrts env' (T::Ts) (map (incr_boundvars 1) Hs) vTs cprf;
           in (Const ("all", (T --> propT) --> propT) $ Abs (s, T, t), Abst (s, Some T, prf),
-            cnstrts, env', ts')
+            cnstrts, env'', vTs')
           end
-      | mk_cnstrts env Ts Hs (t::ts) (AbsP (s, Some _, cprf)) =
+      | mk_cnstrts env Ts Hs vTs (AbsP (s, Some t, cprf)) =
           let
-            val (u, prf, cnstrts, env', ts') = mk_cnstrts env Ts (t::Hs) ts cprf;
-            val t' = strip_abs Ts t;
-          in (Logic.mk_implies (t', u), AbsP (s, Some t', prf), cnstrts, env', ts')
+            val (t', _, vTs', env') = infer_type sg env Ts vTs t;
+            val (u, prf, cnstrts, env'', vTs'') = mk_cnstrts env' Ts (t'::Hs) vTs' cprf;
+          in (Logic.mk_implies (t', u), AbsP (s, Some t', prf), cnstrts, env'', vTs'')
           end
-      | mk_cnstrts env Ts Hs ts (AbsP (s, None, cprf)) =
+      | mk_cnstrts env Ts Hs vTs (AbsP (s, None, cprf)) =
           let
             val (env', t) = mk_var env Ts propT;
-            val (u, prf, cnstrts, env'', ts') = mk_cnstrts env' Ts (t::Hs) ts cprf;
-          in (Logic.mk_implies (t, u), AbsP (s, Some t, prf), cnstrts, env'', ts')
+            val (u, prf, cnstrts, env'', vTs') = mk_cnstrts env' Ts (t::Hs) vTs cprf;
+          in (Logic.mk_implies (t, u), AbsP (s, Some t, prf), cnstrts, env'', vTs')
           end
-      | mk_cnstrts env Ts Hs ts (cprf1 %% cprf2) =
-          let val (u, prf2, cnstrts, env', ts') = mk_cnstrts env Ts Hs ts cprf2
-          in (case mk_cnstrts env' Ts Hs ts' cprf1 of
-              (Const ("==>", _) $ u' $ t', prf1, cnstrts', env'', ts'') =>
+      | mk_cnstrts env Ts Hs vTs (cprf1 %% cprf2) =
+          let val (u, prf2, cnstrts, env', vTs') = mk_cnstrts env Ts Hs vTs cprf2
+          in (case head_norm (mk_cnstrts env' Ts Hs vTs' cprf1) of
+              (Const ("==>", _) $ u' $ t', prf1, cnstrts', env'', vTs'') =>
                 add_cnstrt Ts t' (prf1 %% prf2) (cnstrts' @ cnstrts)
-                  env'' ts'' (u, u')
-            | (t, prf1, cnstrts', env'', ts'') =>
+                  env'' vTs'' (u, u')
+            | (t, prf1, cnstrts', env'', vTs'') =>
                 let val (env''', v) = mk_var env'' Ts propT
                 in add_cnstrt Ts v (prf1 %% prf2) (cnstrts' @ cnstrts)
-                  env''' ts'' (t, Logic.mk_implies (u, v))
+                  env''' vTs'' (t, Logic.mk_implies (u, v))
                 end)
           end
-      | mk_cnstrts env Ts Hs (t::ts) (cprf % Some _) =
-          let val t' = strip_abs Ts t
-          in (case mk_cnstrts env Ts Hs ts cprf of
+      | mk_cnstrts env Ts Hs vTs (cprf % Some t) =
+          let val (t', U, vTs1, env1) = infer_type sg env Ts vTs t
+          in (case head_norm (mk_cnstrts env1 Ts Hs vTs1 cprf) of
              (Const ("all", Type ("fun", [Type ("fun", [T, _]), _])) $ f,
-                 prf, cnstrts, env', ts') =>
-               let val env'' = unifyT sg env' T (Envir.fastype env' Ts t')
-               in (betapply (f, t'), prf % Some t', cnstrts, env'', ts')
+                 prf, cnstrts, env2, vTs2) =>
+               let val env3 = unifyT sg env2 T U
+               in (betapply (f, t'), prf % Some t', cnstrts, env3, vTs2)
                end
-           | (u, prf, cnstrts, env', ts') =>
-               let
-                 val T = Envir.fastype env' Ts t';
-                 val (env'', v) = mk_var env' Ts (T --> propT);
+           | (u, prf, cnstrts, env2, vTs2) =>
+               let val (env3, v) = mk_var env2 Ts (U --> propT);
                in
-                 add_cnstrt Ts (v $ t') (prf % Some t') cnstrts env'' ts'
-                   (u, Const ("all", (T --> propT) --> propT) $ v)
+                 add_cnstrt Ts (v $ t') (prf % Some t') cnstrts env3 vTs2
+                   (u, Const ("all", (U --> propT) --> propT) $ v)
                end)
           end
-      | mk_cnstrts env Ts Hs ts (cprf % None) =
-          (case mk_cnstrts env Ts Hs ts cprf of
+      | mk_cnstrts env Ts Hs vTs (cprf % None) =
+          (case head_norm (mk_cnstrts env Ts Hs vTs cprf) of
              (Const ("all", Type ("fun", [Type ("fun", [T, _]), _])) $ f,
-                 prf, cnstrts, env', ts') =>
+                 prf, cnstrts, env', vTs') =>
                let val (env'', t) = mk_var env' Ts T
-               in (betapply (f, t), prf % Some t, cnstrts, env'', ts')
+               in (betapply (f, t), prf % Some t, cnstrts, env'', vTs')
                end
-           | (u, prf, cnstrts, env', ts') =>
+           | (u, prf, cnstrts, env', vTs') =>
                let
                  val (env1, T) = mk_tvar (env', ["logic"]);
                  val (env2, v) = mk_var env1 Ts (T --> propT);
                  val (env3, t) = mk_var env2 Ts T
                in
-                 add_cnstrt Ts (v $ t) (prf % Some t) cnstrts env3 ts'
+                 add_cnstrt Ts (v $ t) (prf % Some t) cnstrts env3 vTs'
                    (u, Const ("all", (T --> propT) --> propT) $ v)
                end)
-      | mk_cnstrts env _ _ ts (prf as PThm (_, _, prop, opTs)) =
-          mk_cnstrts_atom env ts prop opTs prf
-      | mk_cnstrts env _ _ ts (prf as PAxm (_, prop, opTs)) =
-          mk_cnstrts_atom env ts prop opTs prf
-      | mk_cnstrts env _ _ ts (prf as Oracle (_, prop, opTs)) =
-          mk_cnstrts_atom env ts prop opTs prf
-      | mk_cnstrts env _ _ ts (Hyp t) = (t, Hyp t, [], env, ts)
+      | mk_cnstrts env _ _ vTs (prf as PThm (_, _, prop, opTs)) =
+          mk_cnstrts_atom env vTs prop opTs prf
+      | mk_cnstrts env _ _ vTs (prf as PAxm (_, prop, opTs)) =
+          mk_cnstrts_atom env vTs prop opTs prf
+      | mk_cnstrts env _ _ vTs (prf as Oracle (_, prop, opTs)) =
+          mk_cnstrts_atom env vTs prop opTs prf
+      | mk_cnstrts env _ _ vTs (Hyp t) = (t, Hyp t, [], env, vTs)
       | mk_cnstrts _ _ _ _ _ = error "reconstruct_proof: minimal proof object"
-  in mk_cnstrts env [] [] ts cprf end;
+  in mk_cnstrts env [] [] Symtab.empty cprf end;
 
 fun add_term_ixns (is, Var (i, T)) = add_typ_ixns (i ins is, T)
   | add_term_ixns (is, Free (_, T)) = add_typ_ixns (is, T)
@@ -224,9 +233,7 @@
   | add_term_ixns (is, _) = is;
 
 
-(********************************************************************************
-  update list of free variables of constraints
-*********************************************************************************)
+(**** update list of free variables of constraints ****)
 
 fun upd_constrs env cs =
   let
@@ -243,17 +250,15 @@
           end
   in check_cs cs end;
 
-(********************************************************************************
-  solution of constraints
-*********************************************************************************)
+(**** solution of constraints ****)
 
 fun solve _ [] bigenv = bigenv
   | solve sg cs bigenv =
       let
         fun search env [] = error ("Unsolvable constraints:\n" ^
               Pretty.string_of (Pretty.chunks (map (fn (_, p, _) =>
-                Sign.pretty_term sg (Logic.mk_flexpair (pairself
-                  (Envir.norm_term bigenv) p))) cs)))
+                Display.pretty_flexpair (Sign.pretty_term sg) (pairself
+                  (Envir.norm_term bigenv) p)) cs)))
           | search env ((u, p as (t1, t2), vs)::ps) =
               if u then
                 let
@@ -278,24 +283,14 @@
       end;
 
 
-(********************************************************************************
-  reconstruction of proofs
-*********************************************************************************)
+(**** reconstruction of proofs ****)
 
 fun reconstruct_proof sg prop cprf =
   let
     val (cprf' % Some prop', thawf) = freeze_thaw_prf (cprf % Some prop);
-    val _ = message "Collecting type constraints...";
-    val (Tcs, cprf'', maxidx) = make_Tconstraints_cprf 0 cprf';
-    val (ts, Ts) = ListPair.unzip Tcs;
-    val tsig = Sign.tsig_of sg;
-    val {classrel, arities, ...} = Type.rep_tsig tsig;
-    val _ = message "Solving type constraints...";
-    val (ts', _, unifier) = TypeInfer.infer_types (Sign.pretty_term sg) (Sign.pretty_typ sg)
-      (Sign.const_type sg) classrel arities [] false (K true) ts Ts;
-    val env = Envir.Envir {asol = Vartab.empty, iTs = Vartab.make unifier, maxidx = maxidx};
-    val _ = message "Collecting term constraints...";
-    val (t, prf, cs, env, _) = make_constraints_cprf sg env ts' cprf'';
+    val _ = message "Collecting constraints...";
+    val (t, prf, cs, env, _) = make_constraints_cprf sg
+      (Envir.empty (maxidx_of_proof cprf)) cprf';
     val cs' = map (fn p => (true, p, op union
       (pairself (map (fst o dest_Var) o term_vars) p))) (map (pairself (Envir.norm_term env)) ((t, prop')::cs));
     val _ = message ("Solving remaining constraints (" ^ string_of_int (length cs') ^ ") ...");
@@ -305,7 +300,10 @@
   end;
 
 fun prop_of_atom prop Ts =
-  subst_TVars (map fst (term_tvars prop) ~~ Ts) (forall_intr_vfs prop);
+  let val (prop', fmap) = Type.varify (prop, []);
+  in subst_TVars (map fst (term_tvars prop) @ map snd fmap ~~ Ts)
+    (forall_intr_vfs prop')
+  end;
 
 fun prop_of' Hs (PBound i) = nth_elem (i, Hs)
   | prop_of' Hs (Abst (s, Some T, prf)) =
@@ -327,9 +325,7 @@
 val prop_of = prop_of' [];
 
 
-(********************************************************************************
-  expand and reconstruct subproofs
-*********************************************************************************)
+(**** expand and reconstruct subproofs ****)
 
 fun expand_proof sg thms prf =
   let
@@ -355,7 +351,7 @@
           let
             fun inc i =
               map_proof_terms (Logic.incr_indexes ([], i)) (incr_tvar i);
-            val (maxidx', i, prf, prfs') = (case assoc (prfs, (a, prop)) of
+            val (maxidx', prf, prfs') = (case assoc (prfs, (a, prop)) of
                 None =>
                   let
                     val _ = message ("Reconstructing proof of " ^ a);
@@ -364,15 +360,19 @@
                       (reconstruct_proof sg prop cprf);
                     val (maxidx', prfs', prf) = expand
                       (maxidx_of_proof prf') prfs prf'
-                  in (maxidx' + maxidx + 1, maxidx + 1, inc (maxidx + 1) prf,
+                  in (maxidx' + maxidx + 1, inc (maxidx + 1) prf,
                     ((a, prop), (maxidx', prf)) :: prfs')
                   end
               | Some (maxidx', prf) => (maxidx' + maxidx + 1,
-                  maxidx + 1, inc (maxidx + 1) prf, prfs));
-            val tye = map (fn ((s, j), _) => (s, i + j)) (term_tvars prop) ~~ Ts
+                  inc (maxidx + 1) prf, prfs));
+            val tfrees = term_tfrees prop;
+            val tye = map (fn ((s, j), _) => (s, maxidx + 1 + j))
+              (term_tvars prop) @ map (rpair ~1 o fst) tfrees ~~ Ts;
+            val varify = map_type_tfree (fn p as (a, S) =>
+              if p mem tfrees then TVar ((a, ~1), S) else TFree p)
           in
-            (maxidx', prfs',
-             map_proof_terms (subst_TVars tye) (typ_subst_TVars tye) prf)
+            (maxidx', prfs', map_proof_terms (subst_TVars tye o
+               map_term_types varify) (typ_subst_TVars tye o varify) prf)
           end
       | expand maxidx prfs prf = (maxidx, prfs, prf);