src/HOL/Tools/Sledgehammer/sledgehammer_fol_clause.ML
changeset 37577 5379f41a1322
parent 37575 cfc5e281740f
equal deleted inserted replaced
37576:512cf962d54c 37577:5379f41a1322
     2     Author:     Jia Meng, Cambridge University Computer Laboratory
     2     Author:     Jia Meng, Cambridge University Computer Laboratory
     3     Author:     Jasmin Blanchette, TU Muenchen
     3     Author:     Jasmin Blanchette, TU Muenchen
     4 
     4 
     5 Storing/printing FOL clauses and arity clauses.  Typed equality is
     5 Storing/printing FOL clauses and arity clauses.  Typed equality is
     6 treated differently.
     6 treated differently.
     7 
       
     8 FIXME: combine with sledgehammer_hol_clause!
       
     9 *)
     7 *)
    10 
     8 
    11 signature SLEDGEHAMMER_FOL_CLAUSE =
     9 signature SLEDGEHAMMER_FOL_CLAUSE =
    12 sig
    10 sig
       
    11   type cnf_thm = Clausifier.cnf_thm
       
    12   type name = string * string
       
    13   type name_pool = string Symtab.table * string Symtab.table
       
    14   datatype kind = Axiom | Conjecture
       
    15   datatype type_literal =
       
    16     TyLitVar of string * name |
       
    17     TyLitFree of string * name
       
    18   datatype arLit =
       
    19       TConsLit of class * string * string list
       
    20     | TVarLit of class * string
       
    21   datatype arity_clause = ArityClause of
       
    22    {axiom_name: string, conclLit: arLit, premLits: arLit list}
       
    23   datatype classrel_clause = ClassrelClause of
       
    24    {axiom_name: string, subclass: class, superclass: class}
       
    25   datatype combtyp =
       
    26     TyVar of name |
       
    27     TyFree of name |
       
    28     TyConstr of name * combtyp list
       
    29   datatype combterm =
       
    30     CombConst of name * combtyp * combtyp list (* Const and Free *) |
       
    31     CombVar of name * combtyp |
       
    32     CombApp of combterm * combterm
       
    33   datatype literal = Literal of bool * combterm
       
    34   datatype hol_clause =
       
    35     HOLClause of {clause_id: int, axiom_name: string, th: thm, kind: kind,
       
    36                   literals: literal list, ctypes_sorts: typ list}
       
    37   exception TRIVIAL of unit
       
    38 
    13   val type_wrapper_name : string
    39   val type_wrapper_name : string
    14   val schematic_var_prefix: string
    40   val schematic_var_prefix: string
    15   val fixed_var_prefix: string
    41   val fixed_var_prefix: string
    16   val tvar_prefix: string
    42   val tvar_prefix: string
    17   val tfree_prefix: string
    43   val tfree_prefix: string
    28   val make_schematic_type_var : string * int -> string
    54   val make_schematic_type_var : string * int -> string
    29   val make_fixed_type_var : string -> string
    55   val make_fixed_type_var : string -> string
    30   val make_fixed_const : string -> string
    56   val make_fixed_const : string -> string
    31   val make_fixed_type_const : string -> string
    57   val make_fixed_type_const : string -> string
    32   val make_type_class : string -> string
    58   val make_type_class : string -> string
    33   type name = string * string
       
    34   type name_pool = string Symtab.table * string Symtab.table
       
    35   val empty_name_pool : bool -> name_pool option
    59   val empty_name_pool : bool -> name_pool option
    36   val pool_map : ('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b
    60   val pool_map : ('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b
    37   val nice_name : name -> name_pool option -> string * name_pool option
    61   val nice_name : name -> name_pool option -> string * name_pool option
    38   datatype kind = Axiom | Conjecture
       
    39   datatype type_literal =
       
    40     TyLitVar of string * name |
       
    41     TyLitFree of string * name
       
    42   val type_literals_for_types : typ list -> type_literal list
    62   val type_literals_for_types : typ list -> type_literal list
    43   datatype arLit =
       
    44       TConsLit of class * string * string list
       
    45     | TVarLit of class * string
       
    46   datatype arity_clause = ArityClause of
       
    47    {axiom_name: string, conclLit: arLit, premLits: arLit list}
       
    48   datatype classrel_clause = ClassrelClause of
       
    49    {axiom_name: string, subclass: class, superclass: class}
       
    50   val make_classrel_clauses: theory -> class list -> class list -> classrel_clause list
    63   val make_classrel_clauses: theory -> class list -> class list -> classrel_clause list
    51   val make_arity_clauses: theory -> string list -> class list -> class list * arity_clause list
    64   val make_arity_clauses: theory -> string list -> class list -> class list * arity_clause list
       
    65   val type_of_combterm : combterm -> combtyp
       
    66   val strip_combterm_comb : combterm -> combterm * combterm list
       
    67   val literals_of_term : theory -> term -> literal list * typ list
       
    68   val conceal_skolem_somes :
       
    69     int -> (string * term) list -> term -> (string * term) list * term
       
    70   val is_quasi_fol_theorem : theory -> thm -> bool
       
    71   val make_clause_table : (thm * 'a) list -> (thm * 'a) Termtab.table
       
    72   val tfree_classes_of_terms : term list -> string list
       
    73   val tvar_classes_of_terms : term list -> string list
       
    74   val type_consts_of_terms : theory -> term list -> string list
       
    75   val prepare_clauses :
       
    76     bool -> thm list -> cnf_thm list -> cnf_thm list -> theory
       
    77     -> string vector
       
    78        * (hol_clause list * hol_clause list * hol_clause list * hol_clause list
       
    79           * classrel_clause list * arity_clause list)
    52 end
    80 end
    53 
    81 
    54 structure Sledgehammer_FOL_Clause : SLEDGEHAMMER_FOL_CLAUSE =
    82 structure Sledgehammer_FOL_Clause : SLEDGEHAMMER_FOL_CLAUSE =
    55 struct
    83 struct
       
    84 
       
    85 open Clausifier
    56 
    86 
    57 val type_wrapper_name = "ti"
    87 val type_wrapper_name = "ti"
    58 
    88 
    59 val schematic_var_prefix = "V_";
    89 val schematic_var_prefix = "V_";
    60 val fixed_var_prefix = "v_";
    90 val fixed_var_prefix = "v_";
   238                             the_pool
   268                             the_pool
   239               |> apsnd SOME
   269               |> apsnd SOME
   240 
   270 
   241 (**** Definitions and functions for FOL clauses for TPTP format output ****)
   271 (**** Definitions and functions for FOL clauses for TPTP format output ****)
   242 
   272 
   243 datatype kind = Axiom | Conjecture;
   273 datatype kind = Axiom | Conjecture
   244 
   274 
   245 (**** Isabelle FOL clauses ****)
   275 (**** Isabelle FOL clauses ****)
   246 
   276 
   247 (* The first component is the type class; the second is a TVar or TFree. *)
   277 (* The first component is the type class; the second is a TVar or TFree. *)
   248 datatype type_literal =
   278 datatype type_literal =
   360 
   390 
   361 fun make_arity_clauses thy tycons classes =
   391 fun make_arity_clauses thy tycons classes =
   362   let val (classes', cpairs) = iter_type_class_pairs thy tycons classes
   392   let val (classes', cpairs) = iter_type_class_pairs thy tycons classes
   363   in  (classes', multi_arity_clause cpairs)  end;
   393   in  (classes', multi_arity_clause cpairs)  end;
   364 
   394 
       
   395 datatype combtyp =
       
   396   TyVar of name |
       
   397   TyFree of name |
       
   398   TyConstr of name * combtyp list
       
   399 
       
   400 datatype combterm =
       
   401   CombConst of name * combtyp * combtyp list (* Const and Free *) |
       
   402   CombVar of name * combtyp |
       
   403   CombApp of combterm * combterm
       
   404 
       
   405 datatype literal = Literal of bool * combterm
       
   406 
       
   407 datatype hol_clause =
       
   408   HOLClause of {clause_id: int, axiom_name: string, th: thm, kind: kind,
       
   409                 literals: literal list, ctypes_sorts: typ list}
       
   410 
       
   411 (*********************************************************************)
       
   412 (* convert a clause with type Term.term to a clause with type clause *)
       
   413 (*********************************************************************)
       
   414 
       
   415 (*Result of a function type; no need to check that the argument type matches.*)
       
   416 fun result_type (TyConstr (_, [_, tp2])) = tp2
       
   417   | result_type _ = raise Fail "non-function type"
       
   418 
       
   419 fun type_of_combterm (CombConst (_, tp, _)) = tp
       
   420   | type_of_combterm (CombVar (_, tp)) = tp
       
   421   | type_of_combterm (CombApp (t1, _)) = result_type (type_of_combterm t1)
       
   422 
       
   423 (*gets the head of a combinator application, along with the list of arguments*)
       
   424 fun strip_combterm_comb u =
       
   425     let fun stripc (CombApp(t,u), ts) = stripc (t, u::ts)
       
   426         |   stripc  x =  x
       
   427     in stripc(u,[]) end
       
   428 
       
   429 fun isFalse (Literal (pol, CombConst ((c, _), _, _))) =
       
   430       (pol andalso c = "c_False") orelse (not pol andalso c = "c_True")
       
   431   | isFalse _ = false;
       
   432 
       
   433 fun isTrue (Literal (pol, CombConst ((c, _), _, _))) =
       
   434       (pol andalso c = "c_True") orelse
       
   435       (not pol andalso c = "c_False")
       
   436   | isTrue _ = false;
       
   437 
       
   438 fun isTaut (HOLClause {literals,...}) = exists isTrue literals;
       
   439 
       
   440 fun type_of (Type (a, Ts)) =
       
   441     let val (folTypes,ts) = types_of Ts in
       
   442       (TyConstr (`make_fixed_type_const a, folTypes), ts)
       
   443     end
       
   444   | type_of (tp as TFree (a, _)) = (TyFree (`make_fixed_type_var a), [tp])
       
   445   | type_of (tp as TVar (x, _)) =
       
   446     (TyVar (make_schematic_type_var x, string_of_indexname x), [tp])
       
   447 and types_of Ts =
       
   448     let val (folTyps, ts) = ListPair.unzip (map type_of Ts) in
       
   449       (folTyps, union_all ts)
       
   450     end
       
   451 
       
   452 (* same as above, but no gathering of sort information *)
       
   453 fun simp_type_of (Type (a, Ts)) =
       
   454       TyConstr (`make_fixed_type_const a, map simp_type_of Ts)
       
   455   | simp_type_of (TFree (a, _)) = TyFree (`make_fixed_type_var a)
       
   456   | simp_type_of (TVar (x, _)) =
       
   457     TyVar (make_schematic_type_var x, string_of_indexname x)
       
   458 
       
   459 (* convert a Term.term (with combinators) into a combterm, also accummulate sort info *)
       
   460 fun combterm_of thy (Const (c, T)) =
       
   461       let
       
   462         val (tp, ts) = type_of T
       
   463         val tvar_list =
       
   464           (if String.isPrefix skolem_theory_name c then
       
   465              [] |> Term.add_tvarsT T |> map TVar
       
   466            else
       
   467              (c, T) |> Sign.const_typargs thy)
       
   468           |> map simp_type_of
       
   469         val c' = CombConst (`make_fixed_const c, tp, tvar_list)
       
   470       in  (c',ts)  end
       
   471   | combterm_of _ (Free(v, T)) =
       
   472       let val (tp,ts) = type_of T
       
   473           val v' = CombConst (`make_fixed_var v, tp, [])
       
   474       in  (v',ts)  end
       
   475   | combterm_of _ (Var(v, T)) =
       
   476       let val (tp,ts) = type_of T
       
   477           val v' = CombVar ((make_schematic_var v, string_of_indexname v), tp)
       
   478       in  (v',ts)  end
       
   479   | combterm_of thy (P $ Q) =
       
   480       let val (P', tsP) = combterm_of thy P
       
   481           val (Q', tsQ) = combterm_of thy Q
       
   482       in  (CombApp (P', Q'), union (op =) tsP tsQ)  end
       
   483   | combterm_of _ (t as Abs _) = raise Fail "HOL clause: Abs"
       
   484 
       
   485 fun predicate_of thy ((@{const Not} $ P), pos) = predicate_of thy (P, not pos)
       
   486   | predicate_of thy (t, pos) = (combterm_of thy (Envir.eta_contract t), pos)
       
   487 
       
   488 fun literals_of_term1 args thy (@{const Trueprop} $ P) =
       
   489     literals_of_term1 args thy P
       
   490   | literals_of_term1 args thy (@{const "op |"} $ P $ Q) =
       
   491     literals_of_term1 (literals_of_term1 args thy P) thy Q
       
   492   | literals_of_term1 (lits, ts) thy P =
       
   493     let val ((pred, ts'), pol) = predicate_of thy (P, true) in
       
   494       (Literal (pol, pred) :: lits, union (op =) ts ts')
       
   495     end
       
   496 val literals_of_term = literals_of_term1 ([], [])
       
   497 
       
   498 fun skolem_name i j num_T_args =
       
   499   skolem_prefix ^ (space_implode "_" (map Int.toString [i, j, num_T_args])) ^
       
   500   skolem_infix ^ "g"
       
   501 
       
   502 fun conceal_skolem_somes i skolem_somes t =
       
   503   if exists_Const (curry (op =) @{const_name skolem_id} o fst) t then
       
   504     let
       
   505       fun aux skolem_somes
       
   506               (t as (Const (@{const_name skolem_id}, Type (_, [_, T])) $ _)) =
       
   507           let
       
   508             val (skolem_somes, s) =
       
   509               if i = ~1 then
       
   510                 (skolem_somes, @{const_name undefined})
       
   511               else case AList.find (op aconv) skolem_somes t of
       
   512                 s :: _ => (skolem_somes, s)
       
   513               | [] =>
       
   514                 let
       
   515                   val s = skolem_theory_name ^ "." ^
       
   516                           skolem_name i (length skolem_somes)
       
   517                                         (length (Term.add_tvarsT T []))
       
   518                 in ((s, t) :: skolem_somes, s) end
       
   519           in (skolem_somes, Const (s, T)) end
       
   520         | aux skolem_somes (t1 $ t2) =
       
   521           let
       
   522             val (skolem_somes, t1) = aux skolem_somes t1
       
   523             val (skolem_somes, t2) = aux skolem_somes t2
       
   524           in (skolem_somes, t1 $ t2) end
       
   525         | aux skolem_somes (Abs (s, T, t')) =
       
   526           let val (skolem_somes, t') = aux skolem_somes t' in
       
   527             (skolem_somes, Abs (s, T, t'))
       
   528           end
       
   529         | aux skolem_somes t = (skolem_somes, t)
       
   530     in aux skolem_somes t end
       
   531   else
       
   532     (skolem_somes, t)
       
   533 
       
   534 fun is_quasi_fol_theorem thy =
       
   535   Meson.is_fol_term thy o snd o conceal_skolem_somes ~1 [] o prop_of
       
   536 
       
   537 (* Trivial problem, which resolution cannot handle (empty clause) *)
       
   538 exception TRIVIAL of unit
       
   539 
       
   540 (* making axiom and conjecture clauses *)
       
   541 fun make_clause thy (clause_id, axiom_name, kind, th) skolem_somes =
       
   542   let
       
   543     val (skolem_somes, t) =
       
   544       th |> prop_of |> conceal_skolem_somes clause_id skolem_somes
       
   545     val (lits, ctypes_sorts) = literals_of_term thy t
       
   546   in
       
   547     if forall isFalse lits then
       
   548       raise TRIVIAL ()
       
   549     else
       
   550       (skolem_somes,
       
   551        HOLClause {clause_id = clause_id, axiom_name = axiom_name, th = th,
       
   552                   kind = kind, literals = lits, ctypes_sorts = ctypes_sorts})
       
   553   end
       
   554 
       
   555 fun add_axiom_clause thy (th, ((name, id), _ : thm)) (skolem_somes, clss) =
       
   556   let
       
   557     val (skolem_somes, cls) = make_clause thy (id, name, Axiom, th) skolem_somes
       
   558   in (skolem_somes, clss |> not (isTaut cls) ? cons (name, cls)) end
       
   559 
       
   560 fun make_axiom_clauses thy clauses =
       
   561   ([], []) |> fold_rev (add_axiom_clause thy) clauses |> snd
       
   562 
       
   563 fun make_conjecture_clauses thy =
       
   564   let
       
   565     fun aux _ _ [] = []
       
   566       | aux n skolem_somes (th :: ths) =
       
   567         let
       
   568           val (skolem_somes, cls) =
       
   569             make_clause thy (n, "conjecture", Conjecture, th) skolem_somes
       
   570         in cls :: aux (n + 1) skolem_somes ths end
       
   571   in aux 0 [] end
       
   572 
       
   573 (** Helper clauses **)
       
   574 
       
   575 fun count_combterm (CombConst ((c, _), _, _)) =
       
   576     Symtab.map_entry c (Integer.add 1)
       
   577   | count_combterm (CombVar _) = I
       
   578   | count_combterm (CombApp (t1, t2)) = count_combterm t1 #> count_combterm t2
       
   579 fun count_literal (Literal (_, t)) = count_combterm t
       
   580 fun count_clause (HOLClause {literals, ...}) = fold count_literal literals
       
   581 
       
   582 fun raw_cnf_rules_pairs ps = map (fn (name, thm) => (thm, ((name, 0), thm))) ps
       
   583 fun cnf_helper_thms thy raw =
       
   584   map (`Thm.get_name_hint)
       
   585   #> (if raw then raw_cnf_rules_pairs else cnf_rules_pairs thy)
       
   586 
       
   587 val optional_helpers =
       
   588   [(["c_COMBI", "c_COMBK"], (false, @{thms COMBI_def COMBK_def})),
       
   589    (["c_COMBB", "c_COMBC"], (false, @{thms COMBB_def COMBC_def})),
       
   590    (["c_COMBS"], (false, @{thms COMBS_def}))]
       
   591 val optional_typed_helpers =
       
   592   [(["c_True", "c_False"], (true, @{thms True_or_False})),
       
   593    (["c_If"], (true, @{thms if_True if_False True_or_False}))]
       
   594 val mandatory_helpers = @{thms fequal_imp_equal equal_imp_fequal}
       
   595 
       
   596 val init_counters =
       
   597   Symtab.make (maps (maps (map (rpair 0) o fst))
       
   598                     [optional_helpers, optional_typed_helpers])
       
   599 
       
   600 fun get_helper_clauses thy is_FO full_types conjectures axcls =
       
   601   let
       
   602     val axclauses = map snd (make_axiom_clauses thy axcls)
       
   603     val ct = fold (fold count_clause) [conjectures, axclauses] init_counters
       
   604     fun is_needed c = the (Symtab.lookup ct c) > 0
       
   605     val cnfs =
       
   606       (optional_helpers
       
   607        |> full_types ? append optional_typed_helpers
       
   608        |> maps (fn (ss, (raw, ths)) =>
       
   609                    if exists is_needed ss then cnf_helper_thms thy raw ths
       
   610                    else []))
       
   611       @ (if is_FO then [] else cnf_helper_thms thy false mandatory_helpers)
       
   612   in map snd (make_axiom_clauses thy cnfs) end
       
   613 
       
   614 fun make_clause_table xs =
       
   615   fold (Termtab.update o `(prop_of o fst)) xs Termtab.empty
       
   616 
       
   617 
       
   618 (***************************************************************)
       
   619 (* Type Classes Present in the Axiom or Conjecture Clauses     *)
       
   620 (***************************************************************)
       
   621 
       
   622 fun set_insert (x, s) = Symtab.update (x, ()) s
       
   623 
       
   624 fun add_classes (sorts, cset) = List.foldl set_insert cset (flat sorts)
       
   625 
       
   626 (*Remove this trivial type class*)
       
   627 fun delete_type cset = Symtab.delete_safe (the_single @{sort HOL.type}) cset;
       
   628 
       
   629 fun tfree_classes_of_terms ts =
       
   630   let val sorts_list = map (map #2 o OldTerm.term_tfrees) ts
       
   631   in  Symtab.keys (delete_type (List.foldl add_classes Symtab.empty sorts_list))  end;
       
   632 
       
   633 fun tvar_classes_of_terms ts =
       
   634   let val sorts_list = map (map #2 o OldTerm.term_tvars) ts
       
   635   in  Symtab.keys (delete_type (List.foldl add_classes Symtab.empty sorts_list))  end;
       
   636 
       
   637 (*fold type constructors*)
       
   638 fun fold_type_consts f (Type (a, Ts)) x = fold (fold_type_consts f) Ts (f (a,x))
       
   639   | fold_type_consts _ _ x = x;
       
   640 
       
   641 (*Type constructors used to instantiate overloaded constants are the only ones needed.*)
       
   642 fun add_type_consts_in_term thy =
       
   643   let
       
   644     val const_typargs = Sign.const_typargs thy
       
   645     fun aux (Const x) = fold (fold_type_consts set_insert) (const_typargs x)
       
   646       | aux (Abs (_, _, u)) = aux u
       
   647       | aux (Const (@{const_name skolem_id}, _) $ _) = I
       
   648       | aux (t $ u) = aux t #> aux u
       
   649       | aux _ = I
       
   650   in aux end
       
   651 
       
   652 fun type_consts_of_terms thy ts =
       
   653   Symtab.keys (fold (add_type_consts_in_term thy) ts Symtab.empty);
       
   654 
       
   655 (* Remove existing axiom clauses from the conjecture clauses, as this can
       
   656    dramatically boost an ATP's performance (for some reason). *)
       
   657 fun subtract_cls ax_clauses =
       
   658   filter_out (Termtab.defined (make_clause_table ax_clauses) o prop_of)
       
   659 
       
   660 (* prepare for passing to writer,
       
   661    create additional clauses based on the information from extra_cls *)
       
   662 fun prepare_clauses full_types goal_cls axcls extra_cls thy =
       
   663   let
       
   664     val is_FO = forall (Meson.is_fol_term thy o prop_of) goal_cls
       
   665     val ccls = subtract_cls extra_cls goal_cls
       
   666     val _ = app (fn th => trace_msg (fn _ => Display.string_of_thm_global thy th)) ccls
       
   667     val ccltms = map prop_of ccls
       
   668     and axtms = map (prop_of o #1) extra_cls
       
   669     val subs = tfree_classes_of_terms ccltms
       
   670     and supers = tvar_classes_of_terms axtms
       
   671     and tycons = type_consts_of_terms thy (ccltms @ axtms)
       
   672     (*TFrees in conjecture clauses; TVars in axiom clauses*)
       
   673     val conjectures = make_conjecture_clauses thy ccls
       
   674     val (_, extra_clauses) = ListPair.unzip (make_axiom_clauses thy extra_cls)
       
   675     val (clnames, axiom_clauses) = ListPair.unzip (make_axiom_clauses thy axcls)
       
   676     val helper_clauses =
       
   677       get_helper_clauses thy is_FO full_types conjectures extra_cls
       
   678     val (supers', arity_clauses) = make_arity_clauses thy tycons supers
       
   679     val classrel_clauses = make_classrel_clauses thy subs supers'
       
   680   in
       
   681     (Vector.fromList clnames,
       
   682       (conjectures, axiom_clauses, extra_clauses, helper_clauses, classrel_clauses, arity_clauses))
       
   683   end
       
   684 
   365 end;
   685 end;