src/HOL/Tools/Sledgehammer/sledgehammer_fact_filter.ML
changeset 35865 2f8fb5242799
parent 35828 46cfc4b8112e
child 35963 943e2582dc87
equal deleted inserted replaced
35843:23908b4dbc2f 35865:2f8fb5242799
     2     Author:     Jia Meng, Cambridge University Computer Laboratory, NICTA
     2     Author:     Jia Meng, Cambridge University Computer Laboratory, NICTA
     3 *)
     3 *)
     4 
     4 
     5 signature SLEDGEHAMMER_FACT_FILTER =
     5 signature SLEDGEHAMMER_FACT_FILTER =
     6 sig
     6 sig
     7   type classrelClause = Sledgehammer_FOL_Clause.classrelClause
     7   type classrel_clause = Sledgehammer_FOL_Clause.classrel_clause
     8   type arityClause = Sledgehammer_FOL_Clause.arityClause
     8   type arity_clause = Sledgehammer_FOL_Clause.arity_clause
     9   type axiom_name = Sledgehammer_HOL_Clause.axiom_name
     9   type axiom_name = Sledgehammer_HOL_Clause.axiom_name
    10   type clause = Sledgehammer_HOL_Clause.clause
    10   type hol_clause = Sledgehammer_HOL_Clause.hol_clause
    11   type clause_id = Sledgehammer_HOL_Clause.clause_id
    11   type hol_clause_id = Sledgehammer_HOL_Clause.hol_clause_id
    12   datatype mode = Auto | Fol | Hol
       
    13   val tvar_classes_of_terms : term list -> string list
    12   val tvar_classes_of_terms : term list -> string list
    14   val tfree_classes_of_terms : term list -> string list
    13   val tfree_classes_of_terms : term list -> string list
    15   val type_consts_of_terms : theory -> term list -> string list
    14   val type_consts_of_terms : theory -> term list -> string list
    16   val get_relevant : int -> bool -> Proof.context * (thm list * 'a) -> thm list ->
    15   val get_relevant_facts : int -> bool -> Proof.context * (thm list * 'a) -> thm list ->
    17     (thm * (string * int)) list
    16     (thm * (string * int)) list
    18   val prepare_clauses : bool -> thm list -> thm list ->
    17   val prepare_clauses : bool -> thm list -> thm list ->
    19     (thm * (axiom_name * clause_id)) list ->
    18     (thm * (axiom_name * hol_clause_id)) list ->
    20     (thm * (axiom_name * clause_id)) list -> theory ->
    19     (thm * (axiom_name * hol_clause_id)) list -> theory ->
    21     axiom_name vector *
    20     axiom_name vector *
    22       (clause list * clause list * clause list *
    21       (hol_clause list * hol_clause list * hol_clause list *
    23       clause list * classrelClause list * arityClause list)
    22       hol_clause list * classrel_clause list * arity_clause list)
    24 end;
    23 end;
    25 
    24 
    26 structure Sledgehammer_Fact_Filter : SLEDGEHAMMER_FACT_FILTER =
    25 structure Sledgehammer_Fact_Filter : SLEDGEHAMMER_FACT_FILTER =
    27 struct
    26 struct
    28 
    27 
    29 structure SFC = Sledgehammer_FOL_Clause
    28 open Sledgehammer_FOL_Clause
    30 structure SFP = Sledgehammer_Fact_Preprocessor
    29 open Sledgehammer_Fact_Preprocessor
    31 structure SHC = Sledgehammer_HOL_Clause
    30 open Sledgehammer_HOL_Clause
    32 
    31 
    33 type classrelClause = SFC.classrelClause
    32 type axiom_name = axiom_name
    34 type arityClause = SFC.arityClause
    33 type hol_clause = hol_clause
    35 type axiom_name = SHC.axiom_name
    34 type hol_clause_id = hol_clause_id
    36 type clause = SHC.clause
       
    37 type clause_id = SHC.clause_id
       
    38 
    35 
    39 (********************************************************************)
    36 (********************************************************************)
    40 (* some settings for both background automatic ATP calling procedure*)
    37 (* some settings for both background automatic ATP calling procedure*)
    41 (* and also explicit ATP invocation methods                         *)
    38 (* and also explicit ATP invocation methods                         *)
    42 (********************************************************************)
    39 (********************************************************************)
    43 
    40 
    44 (*Translation mode can be auto-detected, or forced to be first-order or higher-order*)
    41 (* Translation mode can be auto-detected, or forced to be first-order or
       
    42    higher-order *)
    45 datatype mode = Auto | Fol | Hol;
    43 datatype mode = Auto | Fol | Hol;
    46 
    44 
    47 val linkup_logic_mode = Auto;
    45 val translation_mode = Auto;
    48 
    46 
    49 (*** background linkup ***)
    47 (*** background linkup ***)
    50 val run_blacklist_filter = true;
    48 val run_blacklist_filter = true;
    51 
    49 
    52 (*** relevance filter parameters ***)
    50 (*** relevance filter parameters ***)
    57   
    55   
    58 (***************************************************************)
    56 (***************************************************************)
    59 (* Relevance Filtering                                         *)
    57 (* Relevance Filtering                                         *)
    60 (***************************************************************)
    58 (***************************************************************)
    61 
    59 
    62 fun strip_Trueprop (Const("Trueprop",_) $ t) = t
    60 fun strip_Trueprop (@{const Trueprop} $ t) = t
    63   | strip_Trueprop t = t;
    61   | strip_Trueprop t = t;
    64 
    62 
    65 (*A surprising number of theorems contain only a few significant constants.
    63 (*A surprising number of theorems contain only a few significant constants.
    66   These include all induction rules, and other general theorems. Filtering
    64   These include all induction rules, and other general theorems. Filtering
    67   theorems in clause form reveals these complexities in the form of Skolem 
    65   theorems in clause form reveals these complexities in the form of Skolem 
    77 
    75 
    78 (*Including equality in this list might be expected to stop rules like subset_antisym from
    76 (*Including equality in this list might be expected to stop rules like subset_antisym from
    79   being chosen, but for some reason filtering works better with them listed. The
    77   being chosen, but for some reason filtering works better with them listed. The
    80   logical signs All, Ex, &, and --> are omitted because any remaining occurrrences
    78   logical signs All, Ex, &, and --> are omitted because any remaining occurrrences
    81   must be within comprehensions.*)
    79   must be within comprehensions.*)
    82 val standard_consts = ["Trueprop","==>","all","==","op |","Not","op ="];
    80 val standard_consts =
       
    81   [@{const_name Trueprop}, @{const_name "==>"}, @{const_name all},
       
    82    @{const_name "=="}, @{const_name "op |"}, @{const_name Not},
       
    83    @{const_name "op ="}];
    83 
    84 
    84 
    85 
    85 (*** constants with types ***)
    86 (*** constants with types ***)
    86 
    87 
    87 (*An abstraction of Isabelle types*)
    88 (*An abstraction of Isabelle types*)
   231               forall is_Var args andalso uni_mem gctypes ct andalso
   232               forall is_Var args andalso uni_mem gctypes ct andalso
   232                 subset (op =) (Term.add_vars rhs [], Term.add_vars lhs [])
   233                 subset (op =) (Term.add_vars rhs [], Term.add_vars lhs [])
   233             end
   234             end
   234             handle ConstFree => false
   235             handle ConstFree => false
   235     in    
   236     in    
   236         case tm of Const ("Trueprop",_) $ (Const("op =",_) $ lhs $ rhs) => 
   237         case tm of @{const Trueprop} $ (Const(@{const_name "op ="}, _) $ lhs $ rhs) => 
   237                    defs lhs rhs 
   238                    defs lhs rhs 
   238                  | _ => false
   239                  | _ => false
   239     end;
   240     end;
   240 
   241 
   241 type annotd_cls = (thm * (string * int)) * ((string * const_typ list) list);
   242 type annotd_cls = (thm * (string * int)) * ((string * const_typ list) list);
   250     if nnew <= max_new then (map #1 newpairs, [])
   251     if nnew <= max_new then (map #1 newpairs, [])
   251     else 
   252     else 
   252       let val cls = sort compare_pairs newpairs
   253       let val cls = sort compare_pairs newpairs
   253           val accepted = List.take (cls, max_new)
   254           val accepted = List.take (cls, max_new)
   254       in
   255       in
   255         SFP.trace_msg (fn () => ("Number of candidates, " ^ Int.toString nnew ^ 
   256         trace_msg (fn () => ("Number of candidates, " ^ Int.toString nnew ^ 
   256                        ", exceeds the limit of " ^ Int.toString (max_new)));
   257                        ", exceeds the limit of " ^ Int.toString (max_new)));
   257         SFP.trace_msg (fn () => ("Effective pass mark: " ^ Real.toString (#2 (List.last accepted))));
   258         trace_msg (fn () => ("Effective pass mark: " ^ Real.toString (#2 (List.last accepted))));
   258         SFP.trace_msg (fn () => "Actually passed: " ^
   259         trace_msg (fn () => "Actually passed: " ^
   259           space_implode ", " (map (fn (((_,(name,_)),_),_) => name) accepted));
   260           space_implode ", " (map (fn (((_,(name,_)),_),_) => name) accepted));
   260 
   261 
   261         (map #1 accepted, map #1 (List.drop (cls, max_new)))
   262         (map #1 accepted, map #1 (List.drop (cls, max_new)))
   262       end
   263       end
   263   end;
   264   end;
   268             let val (newrels,more_rejects) = take_best max_new newpairs
   269             let val (newrels,more_rejects) = take_best max_new newpairs
   269                 val new_consts = maps #2 newrels
   270                 val new_consts = maps #2 newrels
   270                 val rel_consts' = List.foldl add_const_typ_table rel_consts new_consts
   271                 val rel_consts' = List.foldl add_const_typ_table rel_consts new_consts
   271                 val newp = p + (1.0-p) / convergence
   272                 val newp = p + (1.0-p) / convergence
   272             in
   273             in
   273               SFP.trace_msg (fn () => "relevant this iteration: " ^ Int.toString (length newrels));
   274               trace_msg (fn () => "relevant this iteration: " ^ Int.toString (length newrels));
   274                (map #1 newrels) @ 
   275                (map #1 newrels) @ 
   275                (relevant_clauses max_new thy ctab newp rel_consts' (more_rejects@rejects))
   276                (relevant_clauses max_new thy ctab newp rel_consts' (more_rejects@rejects))
   276             end
   277             end
   277         | relevant (newrels,rejects) ((ax as (clsthm as (_,(name,n)),consts_typs)) :: axs) =
   278         | relevant (newrels,rejects) ((ax as (clsthm as (_,(name,n)),consts_typs)) :: axs) =
   278             let val weight = clause_weight ctab rel_consts consts_typs
   279             let val weight = clause_weight ctab rel_consts consts_typs
   279             in
   280             in
   280               if p <= weight orelse (follow_defs andalso defines thy (#1 clsthm) rel_consts)
   281               if p <= weight orelse (follow_defs andalso defines thy (#1 clsthm) rel_consts)
   281               then (SFP.trace_msg (fn () => (name ^ " clause " ^ Int.toString n ^ 
   282               then (trace_msg (fn () => (name ^ " clause " ^ Int.toString n ^ 
   282                                             " passes: " ^ Real.toString weight));
   283                                             " passes: " ^ Real.toString weight));
   283                     relevant ((ax,weight)::newrels, rejects) axs)
   284                     relevant ((ax,weight)::newrels, rejects) axs)
   284               else relevant (newrels, ax::rejects) axs
   285               else relevant (newrels, ax::rejects) axs
   285             end
   286             end
   286     in  SFP.trace_msg (fn () => ("relevant_clauses, current pass mark = " ^ Real.toString p));
   287     in  trace_msg (fn () => ("relevant_clauses, current pass mark = " ^ Real.toString p));
   287         relevant ([],[]) 
   288         relevant ([],[]) 
   288     end;
   289     end;
   289         
   290         
   290 fun relevance_filter max_new theory_const thy axioms goals = 
   291 fun relevance_filter max_new theory_const thy axioms goals = 
   291  if run_relevance_filter andalso pass_mark >= 0.1
   292  if run_relevance_filter andalso pass_mark >= 0.1
   292  then
   293  then
   293   let val const_tab = List.foldl (count_axiom_consts theory_const thy) Symtab.empty axioms
   294   let val const_tab = List.foldl (count_axiom_consts theory_const thy) Symtab.empty axioms
   294       val goal_const_tab = get_goal_consts_typs thy goals
   295       val goal_const_tab = get_goal_consts_typs thy goals
   295       val _ = SFP.trace_msg (fn () => ("Initial constants: " ^
   296       val _ = trace_msg (fn () => ("Initial constants: " ^
   296                                  space_implode ", " (Symtab.keys goal_const_tab)));
   297                                  space_implode ", " (Symtab.keys goal_const_tab)));
   297       val rels = relevant_clauses max_new thy const_tab (pass_mark) 
   298       val rels = relevant_clauses max_new thy const_tab (pass_mark) 
   298                    goal_const_tab  (map (pair_consts_typs_axiom theory_const thy) axioms)
   299                    goal_const_tab  (map (pair_consts_typs_axiom theory_const thy) axioms)
   299   in
   300   in
   300       SFP.trace_msg (fn () => ("Total relevant: " ^ Int.toString (length rels)));
   301       trace_msg (fn () => ("Total relevant: " ^ Int.toString (length rels)));
   301       rels
   302       rels
   302   end
   303   end
   303  else axioms;
   304  else axioms;
   304 
   305 
   305 (***************************************************************)
   306 (***************************************************************)
   330   | hashw_term ((Var(_,_)), w) = w
   331   | hashw_term ((Var(_,_)), w) = w
   331   | hashw_term ((Bound i), w) = Polyhash.hashw_int(i,w)
   332   | hashw_term ((Bound i), w) = Polyhash.hashw_int(i,w)
   332   | hashw_term ((Abs(_,_,t)), w) = hashw_term (t, w)
   333   | hashw_term ((Abs(_,_,t)), w) = hashw_term (t, w)
   333   | hashw_term ((P$Q), w) = hashw_term (Q, (hashw_term (P, w)));
   334   | hashw_term ((P$Q), w) = hashw_term (Q, (hashw_term (P, w)));
   334 
   335 
   335 fun hash_literal (Const("Not",_)$P) = Word.notb(hashw_term(P,0w0))
   336 fun hash_literal (@{const Not} $ P) = Word.notb(hashw_term(P,0w0))
   336   | hash_literal P = hashw_term(P,0w0);
   337   | hash_literal P = hashw_term(P,0w0);
   337 
   338 
   338 fun hash_term t = Word.toIntX (xor_words (map hash_literal (HOLogic.disjuncts (strip_Trueprop t))));
   339 fun hash_term t = Word.toIntX (xor_words (map hash_literal (HOLogic.disjuncts (strip_Trueprop t))));
   339 
   340 
   340 fun equal_thm (thm1,thm2) = Term.aconv(prop_of thm1, prop_of thm2);
   341 fun equal_thm (thm1,thm2) = Term.aconv(prop_of thm1, prop_of thm2);
   349 (*Use a hash table to eliminate duplicates from xs. Argument is a list of
   350 (*Use a hash table to eliminate duplicates from xs. Argument is a list of
   350   (thm * (string * int)) tuples. The theorems are hashed into the table. *)
   351   (thm * (string * int)) tuples. The theorems are hashed into the table. *)
   351 fun make_unique xs =
   352 fun make_unique xs =
   352   let val ht = mk_clause_table 7000
   353   let val ht = mk_clause_table 7000
   353   in
   354   in
   354       SFP.trace_msg (fn () => ("make_unique gets " ^ Int.toString (length xs) ^ " clauses"));
   355       trace_msg (fn () => ("make_unique gets " ^ Int.toString (length xs) ^ " clauses"));
   355       app (ignore o Polyhash.peekInsert ht) xs;
   356       app (ignore o Polyhash.peekInsert ht) xs;
   356       Polyhash.listItems ht
   357       Polyhash.listItems ht
   357   end;
   358   end;
   358 
   359 
   359 (*Remove existing axiom clauses from the conjecture clauses, as this can dramatically
   360 (*Remove existing axiom clauses from the conjecture clauses, as this can dramatically
   381               NONE => false
   382               NONE => false
   382             | SOME ths1 => Thm.eq_thms (ths0, ths1));
   383             | SOME ths1 => Thm.eq_thms (ths0, ths1));
   383 
   384 
   384           val name1 = Facts.extern facts name;
   385           val name1 = Facts.extern facts name;
   385           val name2 = Name_Space.extern full_space name;
   386           val name2 = Name_Space.extern full_space name;
   386           val ths = filter_out SFP.bad_for_atp ths0;
   387           val ths = filter_out bad_for_atp ths0;
   387         in
   388         in
   388           if Facts.is_concealed facts name orelse null ths orelse
   389           if Facts.is_concealed facts name orelse null ths orelse
   389             run_blacklist_filter andalso is_package_def name then I
   390             run_blacklist_filter andalso is_package_def name then I
   390           else
   391           else
   391             (case find_first check_thms [name1, name2, name] of
   392             (case find_first check_thms [name1, name2, name] of
   401   | add_single_names (a, [th]) pairs = (a, th) :: pairs
   402   | add_single_names (a, [th]) pairs = (a, th) :: pairs
   402   | add_single_names (a, ths) pairs = #2 (fold (multi_name a) ths (1, pairs));
   403   | add_single_names (a, ths) pairs = #2 (fold (multi_name a) ths (1, pairs));
   403 
   404 
   404 (*Ignore blacklisted basenames*)
   405 (*Ignore blacklisted basenames*)
   405 fun add_multi_names (a, ths) pairs =
   406 fun add_multi_names (a, ths) pairs =
   406   if (Long_Name.base_name a) mem_string SFP.multi_base_blacklist then pairs
   407   if (Long_Name.base_name a) mem_string multi_base_blacklist then pairs
   407   else add_single_names (a, ths) pairs;
   408   else add_single_names (a, ths) pairs;
   408 
   409 
   409 fun is_multi (a, ths) = length ths > 1 orelse String.isSuffix ".axioms" a;
   410 fun is_multi (a, ths) = length ths > 1 orelse String.isSuffix ".axioms" a;
   410 
   411 
   411 (*The single theorems go BEFORE the multiple ones. Blacklist is applied to all.*)
   412 (*The single theorems go BEFORE the multiple ones. Blacklist is applied to all.*)
   412 fun name_thm_pairs ctxt =
   413 fun name_thm_pairs ctxt =
   413   let
   414   let
   414     val (mults, singles) = List.partition is_multi (all_valid_thms ctxt)
   415     val (mults, singles) = List.partition is_multi (all_valid_thms ctxt)
   415     val blacklist =
   416     val ps = [] |> fold add_multi_names mults
   416       if run_blacklist_filter then No_ATPs.get ctxt |> map Thm.prop_of else []
   417                 |> fold add_single_names singles
   417     fun is_blacklisted (_, th) = member (op =) blacklist (Thm.prop_of th)
   418   in
   418   in
   419     if run_blacklist_filter then
   419     filter_out is_blacklisted
   420       let
   420       (fold add_single_names singles (fold add_multi_names mults []))
   421         val blacklist = No_ATPs.get ctxt
       
   422                         |> map (`Thm.full_prop_of) |> Termtab.make
       
   423         val is_blacklisted = Termtab.defined blacklist o Thm.full_prop_of o snd
       
   424       in ps |> filter_out is_blacklisted end
       
   425     else
       
   426       ps
   421   end;
   427   end;
   422 
   428 
   423 fun check_named ("", th) =
   429 fun check_named ("", th) =
   424       (warning ("No name for theorem " ^ Display.string_of_thm_without_context th); false)
   430       (warning ("No name for theorem " ^ Display.string_of_thm_without_context th); false)
   425   | check_named _ = true;
   431   | check_named _ = true;
   426 
   432 
   427 fun get_all_lemmas ctxt =
   433 fun get_all_lemmas ctxt =
   428   let val included_thms =
   434   let val included_thms =
   429         tap (fn ths => SFP.trace_msg
   435         tap (fn ths => trace_msg
   430                      (fn () => ("Including all " ^ Int.toString (length ths) ^ " theorems")))
   436                      (fn () => ("Including all " ^ Int.toString (length ths) ^ " theorems")))
   431             (name_thm_pairs ctxt)
   437             (name_thm_pairs ctxt)
   432   in
   438   in
   433     filter check_named included_thms
   439     filter check_named included_thms
   434   end;
   440   end;
   438 (***************************************************************)
   444 (***************************************************************)
   439 
   445 
   440 fun add_classes (sorts, cset) = List.foldl setinsert cset (flat sorts);
   446 fun add_classes (sorts, cset) = List.foldl setinsert cset (flat sorts);
   441 
   447 
   442 (*Remove this trivial type class*)
   448 (*Remove this trivial type class*)
   443 fun delete_type cset = Symtab.delete_safe "HOL.type" cset;
   449 fun delete_type cset = Symtab.delete_safe (the_single @{sort HOL.type}) cset;
   444 
   450 
   445 fun tvar_classes_of_terms ts =
   451 fun tvar_classes_of_terms ts =
   446   let val sorts_list = map (map #2 o OldTerm.term_tvars) ts
   452   let val sorts_list = map (map #2 o OldTerm.term_tvars) ts
   447   in  Symtab.keys (delete_type (List.foldl add_classes Symtab.empty sorts_list))  end;
   453   in  Symtab.keys (delete_type (List.foldl add_classes Symtab.empty sorts_list))  end;
   448 
   454 
   497   (2) those between a variable and a record, since these seem to be prolific "cases" thms
   503   (2) those between a variable and a record, since these seem to be prolific "cases" thms
   498 *)
   504 *)
   499 fun too_general_eqterms (Var (ix,T), t) = not (occurs ix t) orelse is_recordtype T
   505 fun too_general_eqterms (Var (ix,T), t) = not (occurs ix t) orelse is_recordtype T
   500   | too_general_eqterms _ = false;
   506   | too_general_eqterms _ = false;
   501 
   507 
   502 fun too_general_equality (Const ("op =", _) $ x $ y) =
   508 fun too_general_equality (Const (@{const_name "op ="}, _) $ x $ y) =
   503       too_general_eqterms (x,y) orelse too_general_eqterms(y,x)
   509       too_general_eqterms (x,y) orelse too_general_eqterms(y,x)
   504   | too_general_equality _ = false;
   510   | too_general_equality _ = false;
   505 
       
   506 (* tautologous? *)
       
   507 fun is_taut (Const ("Trueprop", _) $ Const ("True", _)) = true
       
   508   | is_taut _ = false;
       
   509 
   511 
   510 fun has_typed_var tycons = exists_subterm
   512 fun has_typed_var tycons = exists_subterm
   511   (fn Var (_, Type (a, _)) => member (op =) tycons a | _ => false);
   513   (fn Var (_, Type (a, _)) => member (op =) tycons a | _ => false);
   512 
   514 
   513 (*Clauses are forbidden to contain variables of these types. The typical reason is that
   515 (*Clauses are forbidden to contain variables of these types. The typical reason is that
   514   they lead to unsoundness. Note that "unit" satisfies numerous equations like ?X=().
   516   they lead to unsoundness. Note that "unit" satisfies numerous equations like ?X=().
   515   The resulting clause will have no type constraint, yielding false proofs. Even "bool"
   517   The resulting clause will have no type constraint, yielding false proofs. Even "bool"
   516   leads to many unsound proofs, though (obviously) only for higher-order problems.*)
   518   leads to many unsound proofs, though (obviously) only for higher-order problems.*)
   517 val unwanted_types = ["Product_Type.unit","bool"];
   519 val unwanted_types = [@{type_name unit}, @{type_name bool}];
   518 
   520 
   519 fun unwanted t =
   521 fun unwanted t =
   520   is_taut t orelse has_typed_var unwanted_types t orelse
   522   t = @{prop True} orelse has_typed_var unwanted_types t orelse
   521   forall too_general_equality (HOLogic.disjuncts (strip_Trueprop t));
   523   forall too_general_equality (HOLogic.disjuncts (strip_Trueprop t));
   522 
   524 
   523 (*Clauses containing variables of type "unit" or "bool" are unlikely to be useful and
   525 (*Clauses containing variables of type "unit" or "bool" are unlikely to be useful and
   524   likely to lead to unsound proofs.*)
   526   likely to lead to unsound proofs.*)
   525 fun remove_unwanted_clauses cls = filter (not o unwanted o prop_of o fst) cls;
   527 fun remove_unwanted_clauses cls = filter (not o unwanted o prop_of o fst) cls;
   526 
   528 
   527 fun isFO thy goal_cls = case linkup_logic_mode of
   529 fun is_first_order thy goal_cls =
   528       Auto => forall (Meson.is_fol_term thy) (map prop_of goal_cls)
   530   case translation_mode of
   529     | Fol => true
   531     Auto => forall (Meson.is_fol_term thy) (map prop_of goal_cls)
   530     | Hol => false
   532   | Fol => true
   531 
   533   | Hol => false
   532 fun get_relevant max_new theory_const (ctxt, (chain_ths, th)) goal_cls =
   534 
       
   535 fun get_relevant_facts max_new theory_const (ctxt, (chain_ths, th)) goal_cls =
   533   let
   536   let
   534     val thy = ProofContext.theory_of ctxt
   537     val thy = ProofContext.theory_of ctxt
   535     val isFO = isFO thy goal_cls
   538     val is_FO = is_first_order thy goal_cls
   536     val included_cls = get_all_lemmas ctxt
   539     val included_cls = get_all_lemmas ctxt
   537       |> SFP.cnf_rules_pairs thy |> make_unique
   540       |> cnf_rules_pairs thy |> make_unique
   538       |> restrict_to_logic thy isFO
   541       |> restrict_to_logic thy is_FO
   539       |> remove_unwanted_clauses
   542       |> remove_unwanted_clauses
   540   in
   543   in
   541     relevance_filter max_new theory_const thy included_cls (map prop_of goal_cls) 
   544     relevance_filter max_new theory_const thy included_cls (map prop_of goal_cls) 
   542   end;
   545   end;
   543 
   546 
   545    create additional clauses based on the information from extra_cls *)
   548    create additional clauses based on the information from extra_cls *)
   546 fun prepare_clauses dfg goal_cls chain_ths axcls extra_cls thy =
   549 fun prepare_clauses dfg goal_cls chain_ths axcls extra_cls thy =
   547   let
   550   let
   548     (* add chain thms *)
   551     (* add chain thms *)
   549     val chain_cls =
   552     val chain_cls =
   550       SFP.cnf_rules_pairs thy (filter check_named (map SFP.pairname chain_ths))
   553       cnf_rules_pairs thy (filter check_named (map pairname chain_ths))
   551     val axcls = chain_cls @ axcls
   554     val axcls = chain_cls @ axcls
   552     val extra_cls = chain_cls @ extra_cls
   555     val extra_cls = chain_cls @ extra_cls
   553     val isFO = isFO thy goal_cls
   556     val is_FO = is_first_order thy goal_cls
   554     val ccls = subtract_cls goal_cls extra_cls
   557     val ccls = subtract_cls goal_cls extra_cls
   555     val _ = app (fn th => SFP.trace_msg (fn _ => Display.string_of_thm_global thy th)) ccls
   558     val _ = app (fn th => trace_msg (fn _ => Display.string_of_thm_global thy th)) ccls
   556     val ccltms = map prop_of ccls
   559     val ccltms = map prop_of ccls
   557     and axtms = map (prop_of o #1) extra_cls
   560     and axtms = map (prop_of o #1) extra_cls
   558     val subs = tfree_classes_of_terms ccltms
   561     val subs = tfree_classes_of_terms ccltms
   559     and supers = tvar_classes_of_terms axtms
   562     and supers = tvar_classes_of_terms axtms
   560     and tycons = type_consts_of_terms thy (ccltms@axtms)
   563     and tycons = type_consts_of_terms thy (ccltms @ axtms)
   561     (*TFrees in conjecture clauses; TVars in axiom clauses*)
   564     (*TFrees in conjecture clauses; TVars in axiom clauses*)
   562     val conjectures = SHC.make_conjecture_clauses dfg thy ccls
   565     val conjectures = make_conjecture_clauses dfg thy ccls
   563     val (_, extra_clauses) = ListPair.unzip (SHC.make_axiom_clauses dfg thy extra_cls)
   566     val (_, extra_clauses) = ListPair.unzip (make_axiom_clauses dfg thy extra_cls)
   564     val (clnames,axiom_clauses) = ListPair.unzip (SHC.make_axiom_clauses dfg thy axcls)
   567     val (clnames, axiom_clauses) = ListPair.unzip (make_axiom_clauses dfg thy axcls)
   565     val helper_clauses = SHC.get_helper_clauses dfg thy isFO (conjectures, extra_cls, [])
   568     val helper_clauses = get_helper_clauses dfg thy is_FO (conjectures, extra_cls, [])
   566     val (supers',arity_clauses) = SFC.make_arity_clauses_dfg dfg thy tycons supers
   569     val (supers', arity_clauses) = make_arity_clauses_dfg dfg thy tycons supers
   567     val classrel_clauses = SFC.make_classrel_clauses thy subs supers'
   570     val classrel_clauses = make_classrel_clauses thy subs supers'
   568   in
   571   in
   569     (Vector.fromList clnames,
   572     (Vector.fromList clnames,
   570       (conjectures, axiom_clauses, extra_clauses, helper_clauses, classrel_clauses, arity_clauses))
   573       (conjectures, axiom_clauses, extra_clauses, helper_clauses, classrel_clauses, arity_clauses))
   571   end
   574   end
   572 
   575 
   573 end;
   576 end;
   574