src/HOL/Tools/Metis/metis_reconstruct.ML
changeset 43135 8c32a0160b0d
parent 43134 0c82e00ba63e
child 43136 cf5cda219058
equal deleted inserted replaced
43134:0c82e00ba63e 43135:8c32a0160b0d
    16   val trace : bool Config.T
    16   val trace : bool Config.T
    17   val trace_msg : Proof.context -> (unit -> string) -> unit
    17   val trace_msg : Proof.context -> (unit -> string) -> unit
    18   val verbose : bool Config.T
    18   val verbose : bool Config.T
    19   val verbose_warning : Proof.context -> string -> unit
    19   val verbose_warning : Proof.context -> string -> unit
    20   val hol_term_from_metis :
    20   val hol_term_from_metis :
    21     mode -> int Symtab.table -> Proof.context -> Metis_Term.term -> term
    21     Proof.context -> mode -> int Symtab.table -> Metis_Term.term -> term
    22   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    22   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    23   val untyped_aconv : term * term -> bool
    23   val untyped_aconv : term * term -> bool
    24   val replay_one_inference :
    24   val replay_one_inference :
    25     Proof.context -> mode -> (string * term) list -> int Symtab.table
    25     Proof.context -> mode -> (string * term) list -> int Symtab.table
    26     -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list
    26     -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list
    51 fun terms_of [] = []
    51 fun terms_of [] = []
    52   | terms_of (SomeTerm t :: tts) = t :: terms_of tts
    52   | terms_of (SomeTerm t :: tts) = t :: terms_of tts
    53   | terms_of (SomeType _ :: tts) = terms_of tts;
    53   | terms_of (SomeType _ :: tts) = terms_of tts;
    54 
    54 
    55 fun types_of [] = []
    55 fun types_of [] = []
    56   | types_of (SomeTerm (Var ((a,idx), _)) :: tts) =
    56   | types_of (SomeTerm (Var ((a, idx), _)) :: tts) =
    57       if String.isPrefix metis_generated_var_prefix a then
    57     types_of tts
    58           (*Variable generated by Metis, which might have been a type variable.*)
    58     |> (if String.isPrefix metis_generated_var_prefix a then
    59           TVar (("'" ^ a, idx), HOLogic.typeS) :: types_of tts
    59           (* Variable generated by Metis, which might have been a type
    60       else types_of tts
    60              variable. *)
       
    61           cons (TVar (("'" ^ a, idx), HOLogic.typeS))
       
    62         else
       
    63           I)
    61   | types_of (SomeTerm _ :: tts) = types_of tts
    64   | types_of (SomeTerm _ :: tts) = types_of tts
    62   | types_of (SomeType T :: tts) = T :: types_of tts;
    65   | types_of (SomeType T :: tts) = T :: types_of tts
    63 
    66 
    64 fun apply_list rator nargs rands =
    67 fun apply_list rator nargs rands =
    65   let val trands = terms_of rands
    68   let val trands = terms_of rands
    66   in  if length trands = nargs then SomeTerm (list_comb(rator, trands))
    69   in  if length trands = nargs then SomeTerm (list_comb(rator, trands))
    67       else raise Fail
    70       else raise Fail
    74   Syntax.check_terms (Proof_Context.set_mode Proof_Context.mode_pattern ctxt);
    77   Syntax.check_terms (Proof_Context.set_mode Proof_Context.mode_pattern ctxt);
    75 
    78 
    76 (* We use 1 rather than 0 because variable references in clauses may otherwise
    79 (* We use 1 rather than 0 because variable references in clauses may otherwise
    77    conflict with variable constraints in the goal...at least, type inference
    80    conflict with variable constraints in the goal...at least, type inference
    78    often fails otherwise. See also "axiom_inf" below. *)
    81    often fails otherwise. See also "axiom_inf" below. *)
    79 fun mk_var (w, T) = Var ((w, 1), T)
    82 fun make_var (w, T) = Var ((w, 1), T)
    80 
       
    81 (*include the default sort, if available*)
       
    82 fun mk_tfree ctxt w =
       
    83   let val ww = "'" ^ w
       
    84   in  TFree(ww, the_default HOLogic.typeS (Variable.def_sort ctxt (ww, ~1)))  end;
       
    85 
    83 
    86 (*Remove the "apply" operator from an HO term*)
    84 (*Remove the "apply" operator from an HO term*)
    87 fun strip_happ args (Metis_Term.Fn (".", [t, u])) = strip_happ (u :: args) t
    85 fun strip_happ args (Metis_Term.Fn (".", [t, u])) = strip_happ (u :: args) t
    88   | strip_happ args x = (x, args)
    86   | strip_happ args x = (x, args)
    89 
       
    90 fun make_tvar s = TVar (("'" ^ s, 0), HOLogic.typeS)
       
    91 
    87 
    92 fun hol_type_from_metis_term _ (Metis_Term.Var v) =
    88 fun hol_type_from_metis_term _ (Metis_Term.Var v) =
    93      (case strip_prefix_and_unascii tvar_prefix v of
    89      (case strip_prefix_and_unascii tvar_prefix v of
    94           SOME w => make_tvar w
    90           SOME w => make_tvar w
    95         | NONE   => make_tvar v)
    91         | NONE   => make_tvar v)
    97      (case strip_prefix_and_unascii type_const_prefix x of
    93      (case strip_prefix_and_unascii type_const_prefix x of
    98           SOME tc => Type (invert_const tc,
    94           SOME tc => Type (invert_const tc,
    99                            map (hol_type_from_metis_term ctxt) tys)
    95                            map (hol_type_from_metis_term ctxt) tys)
   100         | NONE    =>
    96         | NONE    =>
   101       case strip_prefix_and_unascii tfree_prefix x of
    97       case strip_prefix_and_unascii tfree_prefix x of
   102           SOME tf => mk_tfree ctxt tf
    98           SOME tf => make_tfree ctxt tf
   103         | NONE    => raise Fail ("hol_type_from_metis_term: " ^ x));
    99         | NONE    => raise Fail ("hol_type_from_metis_term: " ^ x));
   104 
   100 
   105 (*Maps metis terms to isabelle terms*)
   101 (*Maps metis terms to isabelle terms*)
   106 fun hol_term_from_metis_PT ctxt fol_tm =
   102 fun hol_term_from_metis_PT ctxt fol_tm =
   107   let val thy = Proof_Context.theory_of ctxt
   103   let val thy = Proof_Context.theory_of ctxt
   110       fun tm_to_tt (Metis_Term.Var v) =
   106       fun tm_to_tt (Metis_Term.Var v) =
   111              (case strip_prefix_and_unascii tvar_prefix v of
   107              (case strip_prefix_and_unascii tvar_prefix v of
   112                   SOME w => SomeType (make_tvar w)
   108                   SOME w => SomeType (make_tvar w)
   113                 | NONE =>
   109                 | NONE =>
   114               case strip_prefix_and_unascii schematic_var_prefix v of
   110               case strip_prefix_and_unascii schematic_var_prefix v of
   115                   SOME w => SomeTerm (mk_var (w, HOLogic.typeT))
   111                   SOME w => SomeTerm (make_var (w, HOLogic.typeT))
   116                 | NONE   => SomeTerm (mk_var (v, HOLogic.typeT)))
   112                 | NONE   => SomeTerm (make_var (v, HOLogic.typeT)))
   117                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   113                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   118         | tm_to_tt (Metis_Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   114         | tm_to_tt (Metis_Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   119         | tm_to_tt (t as Metis_Term.Fn (".", _)) =
   115         | tm_to_tt (t as Metis_Term.Fn (".", _)) =
   120             let val (rator,rands) = strip_happ [] t in
   116             let val (rator,rands) = strip_happ [] t in
   121               case rator of
   117               case rator of
   156             case strip_prefix_and_unascii type_const_prefix a of
   152             case strip_prefix_and_unascii type_const_prefix a of
   157                 SOME b =>
   153                 SOME b =>
   158                 SomeType (Type (invert_const b, types_of (map tm_to_tt ts)))
   154                 SomeType (Type (invert_const b, types_of (map tm_to_tt ts)))
   159               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   155               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   160             case strip_prefix_and_unascii tfree_prefix a of
   156             case strip_prefix_and_unascii tfree_prefix a of
   161                 SOME b => SomeType (mk_tfree ctxt b)
   157                 SOME b => SomeType (make_tfree ctxt b)
   162               | NONE => (*a fixed variable? They are Skolem functions.*)
   158               | NONE => (*a fixed variable? They are Skolem functions.*)
   163             case strip_prefix_and_unascii fixed_var_prefix a of
   159             case strip_prefix_and_unascii fixed_var_prefix a of
   164                 SOME b =>
   160                 SOME b =>
   165                   let val opr = Free (b, HOLogic.typeT)
   161                   let val opr = Free (b, HOLogic.typeT)
   166                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   162                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   182           else
   178           else
   183             Const (c, dummyT)
   179             Const (c, dummyT)
   184         end
   180         end
   185       fun cvt (Metis_Term.Fn (":", [Metis_Term.Var v, _])) =
   181       fun cvt (Metis_Term.Fn (":", [Metis_Term.Var v, _])) =
   186              (case strip_prefix_and_unascii schematic_var_prefix v of
   182              (case strip_prefix_and_unascii schematic_var_prefix v of
   187                   SOME w =>  mk_var(w, dummyT)
   183                   SOME w =>  make_var (w, dummyT)
   188                 | NONE   => mk_var(v, dummyT))
   184                 | NONE   => make_var (v, dummyT))
   189         | cvt (Metis_Term.Fn (":", [Metis_Term.Fn ("=",[]), _])) =
   185         | cvt (Metis_Term.Fn (":", [Metis_Term.Fn ("=",[]), _])) =
   190             Const (@{const_name HOL.eq}, HOLogic.typeT)
   186             Const (@{const_name HOL.eq}, HOLogic.typeT)
   191         | cvt (Metis_Term.Fn (":", [Metis_Term.Fn (x,[]), ty])) =
   187         | cvt (Metis_Term.Fn (":", [Metis_Term.Fn (x,[]), ty])) =
   192            (case strip_prefix_and_unascii const_prefix x of
   188            (case strip_prefix_and_unascii const_prefix x of
   193                 SOME c => do_const c
   189                 SOME c => do_const c
   224     let val (s, swap) = atp_name_from_metis s in
   220     let val (s, swap) = atp_name_from_metis s in
   225       ATerm (s, tms |> map atp_term_from_metis |> swap ? rev)
   221       ATerm (s, tms |> map atp_term_from_metis |> swap ? rev)
   226     end
   222     end
   227   | atp_term_from_metis (Metis_Term.Var s) = ATerm (s, [])
   223   | atp_term_from_metis (Metis_Term.Var s) = ATerm (s, [])
   228 
   224 
   229 fun hol_term_from_metis_MX sym_tab ctxt =
   225 fun hol_term_from_metis_MX ctxt sym_tab =
   230   let val thy = Proof_Context.theory_of ctxt in
   226   atp_term_from_metis #> term_from_atp ctxt false sym_tab NONE
   231     atp_term_from_metis #> term_from_atp thy false sym_tab []
   227 
   232     (* FIXME ### tfrees instead of []? *) NONE
   228 fun hol_term_from_metis ctxt FO _ = hol_term_from_metis_PT ctxt
   233   end
   229   | hol_term_from_metis ctxt HO _ = hol_term_from_metis_PT ctxt
   234 
   230   | hol_term_from_metis ctxt FT _ = hol_term_from_metis_FT ctxt
   235 fun hol_term_from_metis FO _ = hol_term_from_metis_PT
   231   | hol_term_from_metis ctxt MX sym_tab = hol_term_from_metis_MX ctxt sym_tab
   236   | hol_term_from_metis HO _ = hol_term_from_metis_PT
       
   237   | hol_term_from_metis FT _ = hol_term_from_metis_FT
       
   238   | hol_term_from_metis MX sym_tab = hol_term_from_metis_MX sym_tab
       
   239 
   232 
   240 fun hol_terms_from_metis ctxt mode old_skolems sym_tab fol_tms =
   233 fun hol_terms_from_metis ctxt mode old_skolems sym_tab fol_tms =
   241   let val ts = map (hol_term_from_metis mode sym_tab ctxt) fol_tms
   234   let val ts = map (hol_term_from_metis ctxt mode sym_tab) fol_tms
   242       val _ = trace_msg ctxt (fn () => "  calling type inference:")
   235       val _ = trace_msg ctxt (fn () => "  calling type inference:")
   243       val _ = app (fn t => trace_msg ctxt
   236       val _ = app (fn t => trace_msg ctxt
   244                                      (fn () => Syntax.string_of_term ctxt t)) ts
   237                                      (fn () => Syntax.string_of_term ctxt t)) ts
   245       val ts' = ts |> map (reveal_old_skolem_terms old_skolems)
   238       val ts' = ts |> map (reveal_old_skolem_terms old_skolems)
   246                    |> infer_types ctxt
   239                    |> infer_types ctxt
   269 
   262 
   270 fun cterm_incr_types thy idx = cterm_of thy o (map_types (Logic.incr_tvar idx));
   263 fun cterm_incr_types thy idx = cterm_of thy o (map_types (Logic.incr_tvar idx));
   271 
   264 
   272 (* INFERENCE RULE: AXIOM *)
   265 (* INFERENCE RULE: AXIOM *)
   273 
   266 
   274 (* This causes variables to have an index of 1 by default. See also "mk_var"
   267 (* This causes variables to have an index of 1 by default. See also "make_var"
   275    above. *)
   268    above. *)
   276 fun axiom_inf th_pairs th = Thm.incr_indexes 1 (lookth th_pairs th)
   269 fun axiom_inf th_pairs th = Thm.incr_indexes 1 (lookth th_pairs th)
   277 
   270 
   278 (* INFERENCE RULE: ASSUME *)
   271 (* INFERENCE RULE: ASSUME *)
   279 
   272 
   302       val i_th_vars = Term.add_vars (prop_of i_th) []
   295       val i_th_vars = Term.add_vars (prop_of i_th) []
   303       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   296       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   304       fun subst_translation (x,y) =
   297       fun subst_translation (x,y) =
   305         let val v = find_var x
   298         let val v = find_var x
   306             (* We call "reveal_old_skolem_terms" and "infer_types" below. *)
   299             (* We call "reveal_old_skolem_terms" and "infer_types" below. *)
   307             val t = hol_term_from_metis mode sym_tab ctxt y
   300             val t = hol_term_from_metis ctxt mode sym_tab y
   308         in  SOME (cterm_of thy (Var v), t)  end
   301         in  SOME (cterm_of thy (Var v), t)  end
   309         handle Option.Option =>
   302         handle Option.Option =>
   310                (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^
   303                (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^
   311                                          " in " ^ Display.string_of_thm ctxt i_th);
   304                                          " in " ^ Display.string_of_thm ctxt i_th);
   312                 NONE)
   305                 NONE)
   338 
   331 
   339 (* INFERENCE RULE: RESOLVE *)
   332 (* INFERENCE RULE: RESOLVE *)
   340 
   333 
   341 (* Like RSN, but we rename apart only the type variables. Vars here typically
   334 (* Like RSN, but we rename apart only the type variables. Vars here typically
   342    have an index of 1, and the use of RSN would increase this typically to 3.
   335    have an index of 1, and the use of RSN would increase this typically to 3.
   343    Instantiations of those Vars could then fail. See comment on "mk_var". *)
   336    Instantiations of those Vars could then fail. See comment on "make_var". *)
   344 fun resolve_inc_tyvars thy tha i thb =
   337 fun resolve_inc_tyvars thy tha i thb =
   345   let
   338   let
   346     val tha = Drule.incr_type_indexes (1 + Thm.maxidx_of thb) tha
   339     val tha = Drule.incr_type_indexes (1 + Thm.maxidx_of thb) tha
   347     fun aux tha thb =
   340     fun aux tha thb =
   348       case Thm.bicompose false (false, tha, nprems_of tha) i thb
   341       case Thm.bicompose false (false, tha, nprems_of tha) i thb