src/HOL/Tools/res_axioms.ML
changeset 28544 26743a1591f5
parent 28262 aa7ca36d67fd
child 28674 08a77c495dc1
equal deleted inserted replaced
28543:637f2808ab64 28544:26743a1591f5
    33 fun type_has_empty_sort (TFree (_, [])) = true
    33 fun type_has_empty_sort (TFree (_, [])) = true
    34   | type_has_empty_sort (TVar (_, [])) = true
    34   | type_has_empty_sort (TVar (_, [])) = true
    35   | type_has_empty_sort (Type (_, Ts)) = exists type_has_empty_sort Ts
    35   | type_has_empty_sort (Type (_, Ts)) = exists type_has_empty_sort Ts
    36   | type_has_empty_sort _ = false;
    36   | type_has_empty_sort _ = false;
    37 
    37 
       
    38 
    38 (**** Transformation of Elimination Rules into First-Order Formulas****)
    39 (**** Transformation of Elimination Rules into First-Order Formulas****)
    39 
    40 
    40 val cfalse = cterm_of HOL.thy HOLogic.false_const;
    41 val cfalse = cterm_of HOL.thy HOLogic.false_const;
    41 val ctp_false = cterm_of HOL.thy (HOLogic.mk_Trueprop HOLogic.false_const);
    42 val ctp_false = cterm_of HOL.thy (HOLogic.mk_Trueprop HOLogic.false_const);
    42 
    43 
    51            Thm.instantiate ([], [(cterm_of HOL.thy v, ctp_false)]) th
    52            Thm.instantiate ([], [(cterm_of HOL.thy v, ctp_false)]) th
    52     | _ => th;
    53     | _ => th;
    53 
    54 
    54 (*To enforce single-threading*)
    55 (*To enforce single-threading*)
    55 exception Clausify_failure of theory;
    56 exception Clausify_failure of theory;
       
    57 
    56 
    58 
    57 (**** SKOLEMIZATION BY INFERENCE (lcp) ****)
    59 (**** SKOLEMIZATION BY INFERENCE (lcp) ****)
    58 
    60 
    59 fun rhs_extra_types lhsT rhs =
    61 fun rhs_extra_types lhsT rhs =
    60   let val lhs_vars = Term.add_tfreesT lhsT []
    62   let val lhs_vars = Term.add_tfreesT lhsT []
    74           let
    76           let
    75             val cname = "sko_" ^ s ^ "_" ^ Int.toString (inc nref)
    77             val cname = "sko_" ^ s ^ "_" ^ Int.toString (inc nref)
    76             val args0 = term_frees xtp  (*get the formal parameter list*)
    78             val args0 = term_frees xtp  (*get the formal parameter list*)
    77             val Ts = map type_of args0
    79             val Ts = map type_of args0
    78             val extraTs = rhs_extra_types (Ts ---> T) xtp
    80             val extraTs = rhs_extra_types (Ts ---> T) xtp
    79             val _ = if null extraTs then () else
       
    80               warning ("Skolemization: extra type vars: " ^
       
    81                 commas_quote (map (Syntax.string_of_typ_global thy) extraTs))
       
    82             val argsx = map (fn T => Free (gensym "vsk", T)) extraTs
    81             val argsx = map (fn T => Free (gensym "vsk", T)) extraTs
    83             val args = argsx @ args0
    82             val args = argsx @ args0
    84             val cT = extraTs ---> Ts ---> T
    83             val cT = extraTs ---> Ts ---> T
    85             val rhs = list_abs_free (map dest_Free args, HOLogic.choice_const T $ xtp)
    84             val rhs = list_abs_free (map dest_Free args, HOLogic.choice_const T $ xtp)
    86                     (*Forms a lambda-abstraction over the formal parameters*)
    85                     (*Forms a lambda-abstraction over the formal parameters*)
   163 val [g_C,f_C] = map (cterm_of (the_context ())) (term_vars (prop_of @{thm abs_C}));
   162 val [g_C,f_C] = map (cterm_of (the_context ())) (term_vars (prop_of @{thm abs_C}));
   164 val [f_S,g_S] = map (cterm_of (the_context ())) (term_vars (prop_of @{thm abs_S}));
   163 val [f_S,g_S] = map (cterm_of (the_context ())) (term_vars (prop_of @{thm abs_S}));
   165 
   164 
   166 (*FIXME: requires more use of cterm constructors*)
   165 (*FIXME: requires more use of cterm constructors*)
   167 fun abstract ct =
   166 fun abstract ct =
   168   let val _ = Output.debug (fn()=>"  abstraction: " ^ Display.string_of_cterm ct)
   167   let
       
   168       val thy = theory_of_cterm ct
   169       val Abs(x,_,body) = term_of ct
   169       val Abs(x,_,body) = term_of ct
   170       val thy = theory_of_cterm ct
       
   171       val Type("fun",[xT,bodyT]) = typ_of (ctyp_of_term ct)
   170       val Type("fun",[xT,bodyT]) = typ_of (ctyp_of_term ct)
   172       val cxT = ctyp_of thy xT and cbodyT = ctyp_of thy bodyT
   171       val cxT = ctyp_of thy xT and cbodyT = ctyp_of thy bodyT
   173       fun makeK() = instantiate' [SOME cxT, SOME cbodyT] [SOME (cterm_of thy body)] @{thm abs_K}
   172       fun makeK() = instantiate' [SOME cxT, SOME cbodyT] [SOME (cterm_of thy body)] @{thm abs_K}
   174   in
   173   in
   175       case body of
   174       case body of
   207             else makeK()
   206             else makeK()
   208         | _ => error "abstract: Bad term"
   207         | _ => error "abstract: Bad term"
   209   end;
   208   end;
   210 
   209 
   211 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   210 (*Traverse a theorem, declaring abstraction function definitions. String s is the suggested
   212   prefix for the constants. Resulting theory is returned in the first theorem. *)
   211   prefix for the constants.*)
   213 fun combinators_aux ct =
   212 fun combinators_aux ct =
   214   if lambda_free (term_of ct) then reflexive ct
   213   if lambda_free (term_of ct) then reflexive ct
   215   else
   214   else
   216   case term_of ct of
   215   case term_of ct of
   217       Abs _ =>
   216       Abs _ =>
   218         let val (cv,cta) = Thm.dest_abs NONE ct
   217         let val (cv,cta) = Thm.dest_abs NONE ct
   219             val (v,Tv) = (dest_Free o term_of) cv
   218             val (v,Tv) = (dest_Free o term_of) cv
   220             val _ = Output.debug (fn()=>"  recursion: " ^ Display.string_of_cterm cta);
       
   221             val u_th = combinators_aux cta
   219             val u_th = combinators_aux cta
   222             val _ = Output.debug (fn()=>"  returned " ^ Display.string_of_thm u_th);
       
   223             val cu = Thm.rhs_of u_th
   220             val cu = Thm.rhs_of u_th
   224             val comb_eq = abstract (Thm.cabs cv cu)
   221             val comb_eq = abstract (Thm.cabs cv cu)
   225         in Output.debug (fn()=>"  abstraction result: " ^ Display.string_of_thm comb_eq);
   222         in transitive (abstract_rule v cv u_th) comb_eq end
   226            (transitive (abstract_rule v cv u_th) comb_eq) end
       
   227     | t1 $ t2 =>
   223     | t1 $ t2 =>
   228         let val (ct1,ct2) = Thm.dest_comb ct
   224         let val (ct1,ct2) = Thm.dest_comb ct
   229         in  combination (combinators_aux ct1) (combinators_aux ct2)  end;
   225         in  combination (combinators_aux ct1) (combinators_aux ct2)  end;
   230 
   226 
   231 fun combinators th =
   227 fun combinators th =
   232   if lambda_free (prop_of th) then th
   228   if lambda_free (prop_of th) then th
   233   else
   229   else
   234     let val _ = Output.debug (fn()=>"Conversion to combinators: " ^ Display.string_of_thm th);
   230     let val th = Drule.eta_contraction_rule th
   235         val th = Drule.eta_contraction_rule th
       
   236         val eqth = combinators_aux (cprop_of th)
   231         val eqth = combinators_aux (cprop_of th)
   237         val _ = Output.debug (fn()=>"Conversion result: " ^ Display.string_of_thm eqth);
       
   238     in  equal_elim eqth th   end
   232     in  equal_elim eqth th   end
   239     handle THM (msg,_,_) =>
   233     handle THM (msg,_,_) =>
   240       (warning ("Error in the combinator translation of " ^ Display.string_of_thm th);
   234       (warning ("Error in the combinator translation of " ^ Display.string_of_thm th);
   241        warning ("  Exception message: " ^ msg);
   235        warning ("  Exception message: " ^ msg);
   242        TrueI);  (*A type variable of sort {} will cause make abstraction fail.*)
   236        TrueI);  (*A type variable of sort {} will cause make abstraction fail.*)
   357       val (nnfth, ctxt1) = to_nnf th ctxt0
   351       val (nnfth, ctxt1) = to_nnf th ctxt0
   358       val (cnfs, ctxt2) = Meson.make_cnf (assume_skolem_of_def s nnfth) nnfth ctxt1
   352       val (cnfs, ctxt2) = Meson.make_cnf (assume_skolem_of_def s nnfth) nnfth ctxt1
   359     in  cnfs |> map combinators |> Variable.export ctxt2 ctxt0 |> Meson.finish_cnf  end
   353     in  cnfs |> map combinators |> Variable.export ctxt2 ctxt0 |> Meson.finish_cnf  end
   360     handle THM _ => [];
   354     handle THM _ => [];
   361 
   355 
   362 (*Declare Skolem functions for a theorem, supplied in nnf and with its name.
       
   363   It returns a modified theory, unless skolemization fails.*)
       
   364 fun skolem (name, th0) thy =
       
   365   let
       
   366     val th = Thm.transfer thy th0
       
   367     val ctxt0 = Variable.thm_context th
       
   368   in
       
   369     try (to_nnf th) ctxt0 |> Option.map (fn (nnfth, ctxt1) =>
       
   370       let
       
   371         val s = flatten_name name
       
   372         val (defs, thy') = declare_skofuns s nnfth thy
       
   373         val (cnfs, ctxt2) = Meson.make_cnf (map skolem_of_def defs) nnfth ctxt1
       
   374         val cnfs' = cnfs |> map combinators |> Variable.export ctxt2 ctxt0
       
   375                          |> Meson.finish_cnf |> map Thm.close_derivation
       
   376       in (cnfs', thy') end)
       
   377   end;
       
   378 
       
   379 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of
   356 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of
   380   Skolem functions.*)
   357   Skolem functions.*)
   381 structure ThmCache = TheoryDataFun
   358 structure ThmCache = TheoryDataFun
   382 (
   359 (
   383   type T = thm list Thmtab.table * unit Symtab.table
   360   type T = thm list Thmtab.table * unit Symtab.table;
   384   val empty = (Thmtab.empty, Symtab.empty)
   361   val empty = (Thmtab.empty, Symtab.empty);
   385   val copy = I;
   362   val copy = I;
   386   val extend = I;
   363   val extend = I;
   387   fun merge _ ((cache1, seen1), (cache2, seen2)) : T =
   364   fun merge _ ((cache1, seen1), (cache2, seen2)) : T =
   388     (Thmtab.merge (K true) (cache1, cache2), Symtab.merge (K true) (seen1, seen2));
   365     (Thmtab.merge (K true) (cache1, cache2), Symtab.merge (K true) (seen1, seen2));
   389 );
   366 );
   409 
   386 
   410 fun rules_of_claset cs =
   387 fun rules_of_claset cs =
   411   let val {safeIs,safeEs,hazIs,hazEs,...} = rep_cs cs
   388   let val {safeIs,safeEs,hazIs,hazEs,...} = rep_cs cs
   412       val intros = safeIs @ hazIs
   389       val intros = safeIs @ hazIs
   413       val elims  = map Classical.classical_rule (safeEs @ hazEs)
   390       val elims  = map Classical.classical_rule (safeEs @ hazEs)
   414   in
   391   in map pairname (intros @ elims) end;
   415      Output.debug (fn () => "rules_of_claset intros: " ^ Int.toString(length intros) ^
       
   416             " elims: " ^ Int.toString(length elims));
       
   417      map pairname (intros @ elims)
       
   418   end;
       
   419 
   392 
   420 fun rules_of_simpset ss =
   393 fun rules_of_simpset ss =
   421   let val ({rules,...}, _) = rep_ss ss
   394   let val ({rules,...}, _) = rep_ss ss
   422       val simps = Net.entries rules
   395       val simps = Net.entries rules
   423   in
   396   in map (fn r => (#name r, #thm r)) simps end;
   424     Output.debug (fn () => "rules_of_simpset: " ^ Int.toString(length simps));
       
   425     map (fn r => (#name r, #thm r)) simps
       
   426   end;
       
   427 
   397 
   428 fun claset_rules_of ctxt = rules_of_claset (local_claset_of ctxt);
   398 fun claset_rules_of ctxt = rules_of_claset (local_claset_of ctxt);
   429 fun simpset_rules_of ctxt = rules_of_simpset (local_simpset_of ctxt);
   399 fun simpset_rules_of ctxt = rules_of_simpset (local_simpset_of ctxt);
   430 
   400 
   431 fun atpset_rules_of ctxt = map pairname (ResAtpset.get ctxt);
   401 fun atpset_rules_of ctxt = map pairname (ResAtpset.get ctxt);
   446 fun cnf_rules_pairs thy l = cnf_rules_pairs_aux thy [] (rev l);
   416 fun cnf_rules_pairs thy l = cnf_rules_pairs_aux thy [] (rev l);
   447 
   417 
   448 
   418 
   449 (**** Convert all facts of the theory into clauses (ResClause.clause, or ResHolClause.clause) ****)
   419 (**** Convert all facts of the theory into clauses (ResClause.clause, or ResHolClause.clause) ****)
   450 
   420 
   451 (*Populate the clause cache using the supplied theorem. Return the clausal form
   421 local
   452   and modified theory.*)
   422 
   453 fun skolem_cache_thm name (i, th) thy =
   423 fun skolem_def (name, th) thy =
   454   if bad_for_atp th then thy
   424   let val ctxt0 = Variable.thm_context th in
   455   else
   425     (case try (to_nnf th) ctxt0 of
   456     (case lookup_cache thy th of
   426       NONE => (NONE, thy)
   457       SOME _ => thy
   427     | SOME (nnfth, ctxt1) =>
   458     | NONE =>
   428         let val (defs, thy') = declare_skofuns (flatten_name name) nnfth thy
   459         (case skolem (name ^ "_" ^ string_of_int (i + 1), th) thy of
   429         in (SOME (th, ctxt0, ctxt1, nnfth, defs), thy') end)
   460           NONE => thy
   430   end;
   461         | SOME (cls, thy') => update_cache (th, cls) thy'));
   431 
   462 
   432 fun skolem_cnfs (th, ctxt0, ctxt1, nnfth, defs) =
   463 fun skolem_cache_fact (name, ths) (changed, thy) =
   433   let
   464   if (Sign.base_name name) mem_string multi_base_blacklist orelse already_seen thy name
   434     val (cnfs, ctxt2) = Meson.make_cnf (map skolem_of_def defs) nnfth ctxt1;
   465   then (changed, thy)
   435     val cnfs' = cnfs
   466   else (true, thy |> mark_seen name |> fold_index (skolem_cache_thm name) ths);
   436       |> map combinators
       
   437       |> Variable.export ctxt2 ctxt0
       
   438       |> Meson.finish_cnf
       
   439       |> map Thm.close_derivation;
       
   440     in (th, cnfs') end;
       
   441 
       
   442 in
   467 
   443 
   468 fun saturate_skolem_cache thy =
   444 fun saturate_skolem_cache thy =
   469   (case Facts.fold_static skolem_cache_fact (PureThy.facts_of thy) (false, thy) of
   445   let
   470     (false, _) => NONE
   446     val new_facts = (PureThy.facts_of thy, []) |-> Facts.fold_static (fn (name, ths) =>
   471   | (true, thy') => SOME thy');
   447       if already_seen thy name then I else cons (name, ths));
   472 
   448     val new_thms = (new_facts, []) |-> fold (fn (name, ths) =>
       
   449       if member (op =) multi_base_blacklist (Sign.base_name name) then I
       
   450       else fold_index (fn (i, th) =>
       
   451         if bad_for_atp th orelse is_some (lookup_cache thy th) then I
       
   452         else cons (name ^ "_" ^ string_of_int (i + 1), Thm.transfer thy th)) ths);
       
   453   in
       
   454     if null new_facts then NONE
       
   455     else
       
   456       let
       
   457         val (defs, thy') = thy
       
   458           |> fold (mark_seen o #1) new_facts
       
   459           |> fold_map skolem_def (sort_distinct (Thm.thm_ord o pairself snd) new_thms)
       
   460           |>> map_filter I;
       
   461         val cache_entries = ParList.map skolem_cnfs defs;
       
   462       in SOME (fold update_cache cache_entries thy') end
       
   463   end;
       
   464 
       
   465 end;
   473 
   466 
   474 val suppress_endtheory = ref false;
   467 val suppress_endtheory = ref false;
   475 
   468 
   476 fun clause_cache_endtheory thy =
   469 fun clause_cache_endtheory thy =
   477   if ! suppress_endtheory then NONE
   470   if ! suppress_endtheory then NONE
   482   lambda_free, but then the individual theory caches become much bigger.*)
   475   lambda_free, but then the individual theory caches become much bigger.*)
   483 
   476 
   484 
   477 
   485 (*** meson proof methods ***)
   478 (*** meson proof methods ***)
   486 
   479 
   487 (*Expand all new*definitions of abstraction or Skolem functions in a proof state.*)
   480 (*Expand all new definitions of abstraction or Skolem functions in a proof state.*)
   488 fun is_absko (Const ("==", _) $ Free (a,_) $ u) = String.isPrefix "sko_" a
   481 fun is_absko (Const ("==", _) $ Free (a,_) $ u) = String.isPrefix "sko_" a
   489   | is_absko _ = false;
   482   | is_absko _ = false;
   490 
   483 
   491 fun is_okdef xs (Const ("==", _) $ t $ u) =   (*Definition of Free, not in certain terms*)
   484 fun is_okdef xs (Const ("==", _) $ t $ u) =   (*Definition of Free, not in certain terms*)
   492       is_Free t andalso not (member (op aconv) xs t)
   485       is_Free t andalso not (member (op aconv) xs t)
   502       val defs = filter (is_absko o Thm.term_of) newhyps
   495       val defs = filter (is_absko o Thm.term_of) newhyps
   503       val remaining_hyps = filter_out (member (op aconv) (map Thm.term_of defs))
   496       val remaining_hyps = filter_out (member (op aconv) (map Thm.term_of defs))
   504                                       (map Thm.term_of hyps)
   497                                       (map Thm.term_of hyps)
   505       val fixed = term_frees (concl_of st) @
   498       val fixed = term_frees (concl_of st) @
   506                   foldl (gen_union (op aconv)) [] (map term_frees remaining_hyps)
   499                   foldl (gen_union (op aconv)) [] (map term_frees remaining_hyps)
   507   in  Output.debug (fn _ => "expand_defs_tac: " ^ Display.string_of_thm st);
   500   in Seq.of_list [LocalDefs.expand (filter (is_okdef fixed o Thm.term_of) defs) st] end;
   508       Output.debug (fn _ => "  st0: " ^ Display.string_of_thm st0);
       
   509       Output.debug (fn _ => "  defs: " ^ commas (map Display.string_of_cterm defs));
       
   510       Seq.of_list [LocalDefs.expand (filter (is_okdef fixed o Thm.term_of) defs) st]
       
   511   end;
       
   512 
   501 
   513 
   502 
   514 fun meson_general_tac ths i st0 =
   503 fun meson_general_tac ths i st0 =
   515   let
   504   let
   516     val thy = Thm.theory_of_thm st0
   505     val thy = Thm.theory_of_thm st0
   517     val _ = Output.debug (fn () => "Meson called: " ^ cat_lines (map Display.string_of_thm ths))
       
   518   in  (Meson.meson_claset_tac (maps (cnf_axiom thy) ths) HOL_cs i THEN expand_defs_tac st0) st0 end;
   506   in  (Meson.meson_claset_tac (maps (cnf_axiom thy) ths) HOL_cs i THEN expand_defs_tac st0) st0 end;
   519 
   507 
   520 val meson_method_setup = Method.add_methods
   508 val meson_method_setup = Method.add_methods
   521   [("meson", Method.thms_args (fn ths =>
   509   [("meson", Method.thms_args (fn ths =>
   522       Method.SIMPLE_METHOD' (CHANGED_PROP o meson_general_tac ths)),
   510       Method.SIMPLE_METHOD' (CHANGED_PROP o meson_general_tac ths)),
   575   setup_attrs #>
   563   setup_attrs #>
   576   perhaps saturate_skolem_cache #>
   564   perhaps saturate_skolem_cache #>
   577   Theory.at_end clause_cache_endtheory;
   565   Theory.at_end clause_cache_endtheory;
   578 
   566 
   579 end;
   567 end;
   580