src/HOL/Tools/Metis/metis_reconstruct.ML
changeset 40259 c0e34371c2e2
parent 40258 2c0d8fe36c21
child 40261 7a02144874f3
equal deleted inserted replaced
40258:2c0d8fe36c21 40259:c0e34371c2e2
    14   val trace : bool Config.T
    14   val trace : bool Config.T
    15   val trace_msg : Proof.context -> (unit -> string) -> unit
    15   val trace_msg : Proof.context -> (unit -> string) -> unit
    16   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    16   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    17   val untyped_aconv : term -> term -> bool
    17   val untyped_aconv : term -> term -> bool
    18   val replay_one_inference :
    18   val replay_one_inference :
    19     Proof.context -> mode -> (string * term) list
    19     Proof.context -> mode -> (string * term) list * int Unsynchronized.ref
    20     -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list
    20     -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list
    21     -> (Metis_Thm.thm * thm) list
    21     -> (Metis_Thm.thm * thm) list
    22   val discharge_skolem_premises :
    22   val discharge_skolem_premises :
    23     Proof.context -> (thm * term) option list -> thm -> thm
    23     Proof.context -> (thm * term) option list -> thm -> thm
    24   val setup : theory -> theory
    24   val setup : theory -> theory
    91       case strip_prefix_and_unascii tfree_prefix x of
    91       case strip_prefix_and_unascii tfree_prefix x of
    92           SOME tf => mk_tfree ctxt tf
    92           SOME tf => mk_tfree ctxt tf
    93         | NONE    => raise Fail ("hol_type_from_metis_term: " ^ x));
    93         | NONE    => raise Fail ("hol_type_from_metis_term: " ^ x));
    94 
    94 
    95 (*Maps metis terms to isabelle terms*)
    95 (*Maps metis terms to isabelle terms*)
    96 fun hol_term_from_metis_PT ctxt fol_tm =
    96 fun hol_term_from_metis_PT ctxt new_skolem_var_count fol_tm =
    97   let val thy = ProofContext.theory_of ctxt
    97   let val thy = ProofContext.theory_of ctxt
    98       val _ = trace_msg ctxt (fn () => "hol_term_from_metis_PT: " ^
    98       val _ = trace_msg ctxt (fn () => "hol_term_from_metis_PT: " ^
    99                                        Metis_Term.toString fol_tm)
    99                                        Metis_Term.toString fol_tm)
   100       fun tm_to_tt (Metis_Term.Var v) =
   100       fun tm_to_tt (Metis_Term.Var v) =
   101              (case strip_prefix_and_unascii tvar_prefix v of
   101              (case strip_prefix_and_unascii tvar_prefix v of
   124                     val c = smart_invert_const b
   124                     val c = smart_invert_const b
   125                     val ntypes = num_type_args thy c
   125                     val ntypes = num_type_args thy c
   126                     val nterms = length ts - ntypes
   126                     val nterms = length ts - ntypes
   127                     val tts = map tm_to_tt ts
   127                     val tts = map tm_to_tt ts
   128                     val tys = types_of (List.take(tts,ntypes))
   128                     val tys = types_of (List.take(tts,ntypes))
       
   129                     val j = !new_skolem_var_count + 1
       
   130                     val _ = new_skolem_var_count := j
   129                     val t =
   131                     val t =
   130                       if String.isPrefix new_skolem_const_prefix c then
   132                       if String.isPrefix new_skolem_const_prefix c then
   131                         Var (new_skolem_var_from_const c,
   133                         Var ((new_skolem_var_name_from_const c, j),
   132                              Type_Infer.paramify_vars (tl tys ---> hd tys))
   134                              Type_Infer.paramify_vars (tl tys ---> hd tys))
   133                       else
   135                       else
   134                         Const (c, dummyT)
   136                         Const (c, dummyT)
   135                   in if length tys = ntypes then
   137                   in if length tys = ntypes then
   136                          apply_list t nterms (List.drop(tts,ntypes))
   138                          apply_list t nterms (List.drop(tts,ntypes))
   160       SomeTerm t => t
   162       SomeTerm t => t
   161     | SomeType T => raise TYPE ("fol_tm_to_tt: Term expected", [T], [])
   163     | SomeType T => raise TYPE ("fol_tm_to_tt: Term expected", [T], [])
   162   end
   164   end
   163 
   165 
   164 (*Maps fully-typed metis terms to isabelle terms*)
   166 (*Maps fully-typed metis terms to isabelle terms*)
   165 fun hol_term_from_metis_FT ctxt fol_tm =
   167 fun hol_term_from_metis_FT ctxt new_skolem_var_count fol_tm =
   166   let val _ = trace_msg ctxt (fn () => "hol_term_from_metis_FT: " ^
   168   let val _ = trace_msg ctxt (fn () => "hol_term_from_metis_FT: " ^
   167                                        Metis_Term.toString fol_tm)
   169                                        Metis_Term.toString fol_tm)
   168       fun cvt (Metis_Term.Fn ("ti", [Metis_Term.Var v, _])) =
   170       fun cvt (Metis_Term.Fn ("ti", [Metis_Term.Var v, _])) =
   169              (case strip_prefix_and_unascii schematic_var_prefix v of
   171              (case strip_prefix_and_unascii schematic_var_prefix v of
   170                   SOME w =>  mk_var(w, dummyT)
   172                   SOME w =>  mk_var(w, dummyT)
   191               | NONE => (*Not a constant. Is it a fixed variable??*)
   193               | NONE => (*Not a constant. Is it a fixed variable??*)
   192             case strip_prefix_and_unascii fixed_var_prefix x of
   194             case strip_prefix_and_unascii fixed_var_prefix x of
   193                 SOME v => Free (v, dummyT)
   195                 SOME v => Free (v, dummyT)
   194               | NONE => (trace_msg ctxt (fn () =>
   196               | NONE => (trace_msg ctxt (fn () =>
   195                                       "hol_term_from_metis_FT bad const: " ^ x);
   197                                       "hol_term_from_metis_FT bad const: " ^ x);
   196                          hol_term_from_metis_PT ctxt t))
   198                          hol_term_from_metis_PT ctxt new_skolem_var_count t))
   197         | cvt t = (trace_msg ctxt (fn () =>
   199         | cvt t = (trace_msg ctxt (fn () =>
   198                    "hol_term_from_metis_FT bad term: " ^ Metis_Term.toString t);
   200                    "hol_term_from_metis_FT bad term: " ^ Metis_Term.toString t);
   199                    hol_term_from_metis_PT ctxt t)
   201                    hol_term_from_metis_PT ctxt new_skolem_var_count t)
   200   in fol_tm |> cvt end
   202   in fol_tm |> cvt end
   201 
   203 
   202 fun hol_term_from_metis FT = hol_term_from_metis_FT
   204 fun hol_term_from_metis FT = hol_term_from_metis_FT
   203   | hol_term_from_metis _ = hol_term_from_metis_PT
   205   | hol_term_from_metis _ = hol_term_from_metis_PT
   204 
   206 
   205 fun hol_terms_from_fol ctxt mode old_skolems fol_tms =
   207 fun hol_terms_from_metis ctxt mode (old_skolems, new_skolem_var_count) fol_tms =
   206   let val ts = map (hol_term_from_metis mode ctxt) fol_tms
   208   let val ts = map (hol_term_from_metis mode ctxt new_skolem_var_count) fol_tms
   207       val _ = trace_msg ctxt (fn () => "  calling type inference:")
   209       val _ = trace_msg ctxt (fn () => "  calling type inference:")
   208       val _ = app (fn t => trace_msg ctxt
   210       val _ = app (fn t => trace_msg ctxt
   209                                      (fn () => Syntax.string_of_term ctxt t)) ts
   211                                      (fn () => Syntax.string_of_term ctxt t)) ts
   210       val ts' = ts |> map (reveal_old_skolem_terms old_skolems)
   212       val ts' = ts |> map (reveal_old_skolem_terms old_skolems)
   211                    |> infer_types ctxt
   213                    |> infer_types ctxt
   247   let val th = EXCLUDED_MIDDLE
   249   let val th = EXCLUDED_MIDDLE
   248       val [vx] = Term.add_vars (prop_of th) []
   250       val [vx] = Term.add_vars (prop_of th) []
   249       val substs = [(cterm_of thy (Var vx), cterm_of thy i_atm)]
   251       val substs = [(cterm_of thy (Var vx), cterm_of thy i_atm)]
   250   in  cterm_instantiate substs th  end;
   252   in  cterm_instantiate substs th  end;
   251 
   253 
   252 fun assume_inf ctxt mode old_skolems atm =
   254 fun assume_inf ctxt mode skolem_params atm =
   253   inst_excluded_middle
   255   inst_excluded_middle
   254       (ProofContext.theory_of ctxt)
   256       (ProofContext.theory_of ctxt)
   255       (singleton (hol_terms_from_fol ctxt mode old_skolems) (Metis_Term.Fn atm))
   257       (singleton (hol_terms_from_metis ctxt mode skolem_params)
       
   258                  (Metis_Term.Fn atm))
   256 
   259 
   257 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying
   260 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying
   258    to reconstruct them admits new possibilities of errors, e.g. concerning
   261    to reconstruct them admits new possibilities of errors, e.g. concerning
   259    sorts. Instead we try to arrange that new TVars are distinct and that types
   262    sorts. Instead we try to arrange that new TVars are distinct and that types
   260    can be inferred from terms. *)
   263    can be inferred from terms. *)
   261 
   264 
   262 fun inst_inf ctxt mode old_skolems thpairs fsubst th =
   265 fun inst_inf ctxt mode (old_skolems, new_skolem_var_count) thpairs fsubst th =
   263   let val thy = ProofContext.theory_of ctxt
   266   let val thy = ProofContext.theory_of ctxt
   264       val i_th = lookth thpairs th
   267       val i_th = lookth thpairs th
   265       val i_th_vars = Term.add_vars (prop_of i_th) []
   268       val i_th_vars = Term.add_vars (prop_of i_th) []
   266       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   269       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   267       fun subst_translation (x,y) =
   270       fun subst_translation (x,y) =
   268         let val v = find_var x
   271         let val v = find_var x
   269             (* We call "reveal_old_skolem_terms" and "infer_types" below. *)
   272             (* We call "reveal_old_skolem_terms" and "infer_types" below. *)
   270             val t = hol_term_from_metis mode ctxt y
   273             val t = hol_term_from_metis mode ctxt new_skolem_var_count y
   271         in  SOME (cterm_of thy (Var v), t)  end
   274         in  SOME (cterm_of thy (Var v), t)  end
   272         handle Option.Option =>
   275         handle Option.Option =>
   273                (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^
   276                (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^
   274                                          " in " ^ Display.string_of_thm ctxt i_th);
   277                                          " in " ^ Display.string_of_thm ctxt i_th);
   275                 NONE)
   278                 NONE)
   373 val negate_head = rewrite_rule [@{thm atomize_not}, not_not RS eq_reflection]
   376 val negate_head = rewrite_rule [@{thm atomize_not}, not_not RS eq_reflection]
   374 
   377 
   375 (* Maps the clause  [P1,...Pn]==>False to [P1,...,P(i-1),P(i+1),...Pn] ==> ~P *)
   378 (* Maps the clause  [P1,...Pn]==>False to [P1,...,P(i-1),P(i+1),...Pn] ==> ~P *)
   376 val select_literal = negate_head oo make_last
   379 val select_literal = negate_head oo make_last
   377 
   380 
   378 fun resolve_inf ctxt mode old_skolems thpairs atm th1 th2 =
   381 fun resolve_inf ctxt mode skolem_params thpairs atm th1 th2 =
   379   let
   382   let
   380     val thy = ProofContext.theory_of ctxt
   383     val thy = ProofContext.theory_of ctxt
   381     val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2
   384     val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2
   382     val _ = trace_msg ctxt (fn () => "  isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1)
   385     val _ = trace_msg ctxt (fn () => "  isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1)
   383     val _ = trace_msg ctxt (fn () => "  isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2)
   386     val _ = trace_msg ctxt (fn () => "  isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2)
   388     else if Thm.eq_thm (TrueI, i_th2) then
   391     else if Thm.eq_thm (TrueI, i_th2) then
   389       i_th1
   392       i_th1
   390     else
   393     else
   391       let
   394       let
   392         val i_atm =
   395         val i_atm =
   393           singleton (hol_terms_from_fol ctxt mode old_skolems)
   396           singleton (hol_terms_from_metis ctxt mode skolem_params)
   394                     (Metis_Term.Fn atm)
   397                     (Metis_Term.Fn atm)
   395         val _ = trace_msg ctxt (fn () => "  atom: " ^ Syntax.string_of_term ctxt i_atm)
   398         val _ = trace_msg ctxt (fn () => "  atom: " ^ Syntax.string_of_term ctxt i_atm)
   396         val prems_th1 = prems_of i_th1
   399         val prems_th1 = prems_of i_th1
   397         val prems_th2 = prems_of i_th2
   400         val prems_th2 = prems_of i_th2
   398         val index_th1 =
   401         val index_th1 =
   413 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp}
   416 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp}
   414 
   417 
   415 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) [])));
   418 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) [])));
   416 val refl_idx = 1 + Thm.maxidx_of REFL_THM;
   419 val refl_idx = 1 + Thm.maxidx_of REFL_THM;
   417 
   420 
   418 fun refl_inf ctxt mode old_skolems t =
   421 fun refl_inf ctxt mode skolem_params t =
   419   let val thy = ProofContext.theory_of ctxt
   422   let val thy = ProofContext.theory_of ctxt
   420       val i_t = singleton (hol_terms_from_fol ctxt mode old_skolems) t
   423       val i_t = singleton (hol_terms_from_metis ctxt mode skolem_params) t
   421       val _ = trace_msg ctxt (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   424       val _ = trace_msg ctxt (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   422       val c_t = cterm_incr_types thy refl_idx i_t
   425       val c_t = cterm_incr_types thy refl_idx i_t
   423   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   426   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   424 
   427 
   425 (* INFERENCE RULE: EQUALITY *)
   428 (* INFERENCE RULE: EQUALITY *)
   431 
   434 
   432 fun get_ty_arg_size _ (Const (@{const_name HOL.eq}, _)) = 0  (*equality has no type arguments*)
   435 fun get_ty_arg_size _ (Const (@{const_name HOL.eq}, _)) = 0  (*equality has no type arguments*)
   433   | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0)
   436   | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0)
   434   | get_ty_arg_size _ _ = 0;
   437   | get_ty_arg_size _ _ = 0;
   435 
   438 
   436 fun equality_inf ctxt mode old_skolems (pos, atm) fp fr =
   439 fun equality_inf ctxt mode skolem_params (pos, atm) fp fr =
   437   let val thy = ProofContext.theory_of ctxt
   440   let val thy = ProofContext.theory_of ctxt
   438       val m_tm = Metis_Term.Fn atm
   441       val m_tm = Metis_Term.Fn atm
   439       val [i_atm,i_tm] = hol_terms_from_fol ctxt mode old_skolems [m_tm, fr]
   442       val [i_atm,i_tm] = hol_terms_from_metis ctxt mode skolem_params [m_tm, fr]
   440       val _ = trace_msg ctxt (fn () => "sign of the literal: " ^ Bool.toString pos)
   443       val _ = trace_msg ctxt (fn () => "sign of the literal: " ^ Bool.toString pos)
   441       fun replace_item_list lx 0 (_::ls) = lx::ls
   444       fun replace_item_list lx 0 (_::ls) = lx::ls
   442         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   445         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   443       fun path_finder_FO tm [] = (tm, Bound 0)
   446       fun path_finder_FO tm [] = (tm, Bound 0)
   444         | path_finder_FO tm (p::ps) =
   447         | path_finder_FO tm (p::ps) =
   513         (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   516         (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   514   in  cterm_instantiate eq_terms subst'  end;
   517   in  cterm_instantiate eq_terms subst'  end;
   515 
   518 
   516 val factor = Seq.hd o distinct_subgoals_tac;
   519 val factor = Seq.hd o distinct_subgoals_tac;
   517 
   520 
   518 fun step ctxt mode old_skolems thpairs p =
   521 fun step ctxt mode skolem_params thpairs p =
   519   case p of
   522   case p of
   520     (fol_th, Metis_Proof.Axiom _) => factor (axiom_inf thpairs fol_th)
   523     (fol_th, Metis_Proof.Axiom _) => factor (axiom_inf thpairs fol_th)
   521   | (_, Metis_Proof.Assume f_atm) => assume_inf ctxt mode old_skolems f_atm
   524   | (_, Metis_Proof.Assume f_atm) => assume_inf ctxt mode skolem_params f_atm
   522   | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) =>
   525   | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) =>
   523     factor (inst_inf ctxt mode old_skolems thpairs f_subst f_th1)
   526     factor (inst_inf ctxt mode skolem_params thpairs f_subst f_th1)
   524   | (_, Metis_Proof.Resolve(f_atm, f_th1, f_th2)) =>
   527   | (_, Metis_Proof.Resolve(f_atm, f_th1, f_th2)) =>
   525     factor (resolve_inf ctxt mode old_skolems thpairs f_atm f_th1 f_th2)
   528     factor (resolve_inf ctxt mode skolem_params thpairs f_atm f_th1 f_th2)
   526   | (_, Metis_Proof.Refl f_tm) => refl_inf ctxt mode old_skolems f_tm
   529   | (_, Metis_Proof.Refl f_tm) => refl_inf ctxt mode skolem_params f_tm
   527   | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) =>
   530   | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) =>
   528     equality_inf ctxt mode old_skolems f_lit f_p f_r
   531     equality_inf ctxt mode skolem_params f_lit f_p f_r
   529 
   532 
   530 fun flexflex_first_order th =
   533 fun flexflex_first_order th =
   531   case Thm.tpairs_of th of
   534   case Thm.tpairs_of th of
   532       [] => th
   535       [] => th
   533     | pairs =>
   536     | pairs =>
   543 fun is_isabelle_literal_genuine t =
   546 fun is_isabelle_literal_genuine t =
   544   case t of _ $ (Const (@{const_name Meson.skolem}, _) $ _) => false | _ => true
   547   case t of _ $ (Const (@{const_name Meson.skolem}, _) $ _) => false | _ => true
   545 
   548 
   546 fun count p xs = fold (fn x => if p x then Integer.add 1 else I) xs 0
   549 fun count p xs = fold (fn x => if p x then Integer.add 1 else I) xs 0
   547 
   550 
   548 fun replay_one_inference ctxt mode old_skolems (fol_th, inf) thpairs =
   551 fun replay_one_inference ctxt mode skolem_params (fol_th, inf) thpairs =
   549   let
   552   let
   550     val _ = trace_msg ctxt (fn () => "=============================================")
   553     val _ = trace_msg ctxt (fn () => "=============================================")
   551     val _ = trace_msg ctxt (fn () => "METIS THM: " ^ Metis_Thm.toString fol_th)
   554     val _ = trace_msg ctxt (fn () => "METIS THM: " ^ Metis_Thm.toString fol_th)
   552     val _ = trace_msg ctxt (fn () => "INFERENCE: " ^ Metis_Proof.inferenceToString inf)
   555     val _ = trace_msg ctxt (fn () => "INFERENCE: " ^ Metis_Proof.inferenceToString inf)
   553     val th = step ctxt mode old_skolems thpairs (fol_th, inf)
   556     val th = step ctxt mode skolem_params thpairs (fol_th, inf)
   554              |> flexflex_first_order
   557              |> flexflex_first_order
   555     val _ = trace_msg ctxt (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th)
   558     val _ = trace_msg ctxt (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th)
   556     val _ = trace_msg ctxt (fn () => "=============================================")
   559     val _ = trace_msg ctxt (fn () => "=============================================")
   557     val num_metis_lits =
   560     val num_metis_lits =
   558       fol_th |> Metis_Thm.clause |> Metis_LiteralSet.toList
   561       fol_th |> Metis_Thm.clause |> Metis_LiteralSet.toList