src/HOL/Tools/ATP_Manager/atp_systems.ML
changeset 38005 b6555e9c5de4
parent 38004 43fdc7c259ea
child 38009 34e1ac9cb71d
equal deleted inserted replaced
38004:43fdc7c259ea 38005:b6555e9c5de4
   185                     (length Ts - 1 downto 0 ~~ rev Ts), t)
   185                     (length Ts - 1 downto 0 ~~ rev Ts), t)
   186 fun reveal_bounds Ts =
   186 fun reveal_bounds Ts =
   187   subst_atomic (map (fn (j, T) => (Free (concealed_bound_name j, T), Bound j))
   187   subst_atomic (map (fn (j, T) => (Free (concealed_bound_name j, T), Bound j))
   188                     (0 upto length Ts - 1 ~~ Ts))
   188                     (0 upto length Ts - 1 ~~ Ts))
   189 
   189 
   190 fun introduce_combinators_in_term thy t =
   190 fun introduce_combinators_in_term ctxt kind t =
   191   let
   191   let
       
   192     val thy = ProofContext.theory_of ctxt
   192     fun aux Ts t =
   193     fun aux Ts t =
   193       case t of
   194       case t of
   194         @{const Not} $ t1 => @{const Not} $ aux Ts t1
   195         @{const Not} $ t1 => @{const Not} $ aux Ts t1
   195       | (t0 as Const (@{const_name All}, _)) $ Abs (s, T, t') =>
   196       | (t0 as Const (@{const_name All}, _)) $ Abs (s, T, t') =>
   196         t0 $ Abs (s, T, aux (T :: Ts) t')
   197         t0 $ Abs (s, T, aux (T :: Ts) t')
   203           $ t1 $ t2 =>
   204           $ t1 $ t2 =>
   204         t0 $ aux Ts t1 $ aux Ts t2
   205         t0 $ aux Ts t1 $ aux Ts t2
   205       | _ => if not (exists_subterm (fn Abs _ => true | _ => false) t) then
   206       | _ => if not (exists_subterm (fn Abs _ => true | _ => false) t) then
   206                t
   207                t
   207              else
   208              else
   208                t |> conceal_bounds Ts
   209                let
   209                  |> Envir.eta_contract
   210                  val t = t |> conceal_bounds Ts
   210                  |> cterm_of thy
   211                            |> Envir.eta_contract
   211                  |> Clausifier.introduce_combinators_in_cterm
   212                  val ([t], ctxt') = Variable.import_terms true [t] ctxt
   212                  |> prop_of |> Logic.dest_equals |> snd
   213                in
   213                  |> reveal_bounds Ts
   214                  t |> cterm_of thy
   214                handle THM (msg, _, _) =>
   215                    |> Clausifier.introduce_combinators_in_cterm
   215                       (* A type variable of sort "{}" will make abstraction
   216                    |> singleton (Variable.export ctxt' ctxt)
   216                          fail. *)
   217                    |> prop_of |> Logic.dest_equals |> snd
   217                       t
   218                    |> reveal_bounds Ts
       
   219                end
   218   in t |> not (Meson.is_fol_term thy t) ? aux [] end
   220   in t |> not (Meson.is_fol_term thy t) ? aux [] end
       
   221   handle THM _ =>
       
   222          (* A type variable of sort "{}" will make abstraction fail. *)
       
   223          case kind of
       
   224            Axiom => HOLogic.true_const
       
   225          | Conjecture => HOLogic.false_const
   219 
   226 
   220 (* making axiom and conjecture clauses *)
   227 (* making axiom and conjecture clauses *)
   221 fun make_clause thy (formula_name, kind, t) =
   228 fun make_clause ctxt (formula_name, kind, t) =
   222   let
   229   let
       
   230     val thy = ProofContext.theory_of ctxt
   223     (* ### FIXME: perform other transformations previously done by
   231     (* ### FIXME: perform other transformations previously done by
   224        "Clausifier.to_nnf", e.g. "HOL.If" *)
   232        "Clausifier.to_nnf", e.g. "HOL.If" *)
   225     val t = t |> transform_elim_term
   233     val t = t |> transform_elim_term
   226               |> Object_Logic.atomize_term thy
   234               |> Object_Logic.atomize_term thy
   227               |> extensionalize_term
   235               |> extensionalize_term
   228               |> introduce_combinators_in_term thy
   236               |> introduce_combinators_in_term ctxt kind
   229     val (combformula, ctypes_sorts) = combformula_for_prop thy t []
   237     val (combformula, ctypes_sorts) = combformula_for_prop thy t []
   230   in
   238   in
   231     FOLFormula {formula_name = formula_name, combformula = combformula,
   239     FOLFormula {formula_name = formula_name, combformula = combformula,
   232                 kind = kind, ctypes_sorts = ctypes_sorts}
   240                 kind = kind, ctypes_sorts = ctypes_sorts}
   233   end
   241   end
   234 
   242 
   235 fun make_axiom_clause thy (name, th) =
   243 fun make_axiom_clause ctxt (name, th) =
   236   (name, make_clause thy (name, Axiom, prop_of th))
   244   (name, make_clause ctxt (name, Axiom, prop_of th))
   237 fun make_conjecture_clauses thy ts =
   245 fun make_conjecture_clauses ctxt ts =
   238   map2 (fn j => fn t => make_clause thy (Int.toString j, Conjecture, t))
   246   map2 (fn j => fn t => make_clause ctxt (Int.toString j, Conjecture, t))
   239        (0 upto length ts - 1) ts
   247        (0 upto length ts - 1) ts
   240 
   248 
   241 (** Helper clauses **)
   249 (** Helper clauses **)
   242 
   250 
   243 fun count_combterm (CombConst ((s, _), _, _)) =
   251 fun count_combterm (CombConst ((s, _), _, _)) =
   261 
   269 
   262 val init_counters =
   270 val init_counters =
   263   Symtab.make (maps (maps (map (rpair 0) o fst))
   271   Symtab.make (maps (maps (map (rpair 0) o fst))
   264                     [optional_helpers, optional_typed_helpers])
   272                     [optional_helpers, optional_typed_helpers])
   265 
   273 
   266 fun get_helper_clauses thy is_FO full_types conjectures axclauses =
   274 fun get_helper_clauses ctxt is_FO full_types conjectures axclauses =
   267   let
   275   let
   268     val ct = fold (fold count_fol_formula) [conjectures, axclauses]
   276     val ct = fold (fold count_fol_formula) [conjectures, axclauses]
   269                   init_counters
   277                   init_counters
   270     fun is_needed c = the (Symtab.lookup ct c) > 0
   278     fun is_needed c = the (Symtab.lookup ct c) > 0
   271     val cnfs =
   279     val cnfs =
   273        |> full_types ? append optional_typed_helpers
   281        |> full_types ? append optional_typed_helpers
   274        |> maps (fn (ss, ths) =>
   282        |> maps (fn (ss, ths) =>
   275                    if exists is_needed ss then map (`Thm.get_name_hint) ths
   283                    if exists is_needed ss then map (`Thm.get_name_hint) ths
   276                    else [])) @
   284                    else [])) @
   277       (if is_FO then [] else map (`Thm.get_name_hint) mandatory_helpers)
   285       (if is_FO then [] else map (`Thm.get_name_hint) mandatory_helpers)
   278   in map (snd o make_axiom_clause thy) cnfs end
   286   in map (snd o make_axiom_clause ctxt) cnfs end
   279 
   287 
   280 fun s_not (@{const Not} $ t) = t
   288 fun s_not (@{const Not} $ t) = t
   281   | s_not t = @{const Not} $ t
   289   | s_not t = @{const Not} $ t
   282 
   290 
   283 (* prepare for passing to writer,
   291 (* prepare for passing to writer,
   284    create additional clauses based on the information from extra_cls *)
   292    create additional clauses based on the information from extra_cls *)
   285 fun prepare_clauses full_types hyp_ts concl_t axcls extra_cls thy =
   293 fun prepare_clauses ctxt full_types hyp_ts concl_t axcls extra_cls =
   286   let
   294   let
       
   295     val thy = ProofContext.theory_of ctxt
   287     val goal_t = Logic.list_implies (hyp_ts, concl_t)
   296     val goal_t = Logic.list_implies (hyp_ts, concl_t)
   288     val is_FO = Meson.is_fol_term thy goal_t
   297     val is_FO = Meson.is_fol_term thy goal_t
   289     val _ = trace_msg (fn _ => Syntax.string_of_term_global thy goal_t)
   298     val _ = trace_msg (fn _ => Syntax.string_of_term ctxt goal_t)
   290     val axtms = map (prop_of o snd) extra_cls
   299     val axtms = map (prop_of o snd) extra_cls
   291     val subs = tfree_classes_of_terms [goal_t]
   300     val subs = tfree_classes_of_terms [goal_t]
   292     val supers = tvar_classes_of_terms axtms
   301     val supers = tvar_classes_of_terms axtms
   293     val tycons = type_consts_of_terms thy (goal_t :: axtms)
   302     val tycons = type_consts_of_terms thy (goal_t :: axtms)
   294     (* TFrees in conjecture clauses; TVars in axiom clauses *)
   303     (* TFrees in conjecture clauses; TVars in axiom clauses *)
   295     val conjectures = make_conjecture_clauses thy (map s_not hyp_ts @ [concl_t])
   304     val conjectures =
   296     val extra_clauses = map (snd o make_axiom_clause thy) extra_cls
   305       map (s_not o HOLogic.dest_Trueprop) hyp_ts @
       
   306         [HOLogic.dest_Trueprop concl_t]
       
   307       |> make_conjecture_clauses ctxt
       
   308     val extra_clauses = map (snd o make_axiom_clause ctxt) extra_cls
   297     val (clnames, axiom_clauses) =
   309     val (clnames, axiom_clauses) =
   298       ListPair.unzip (map (make_axiom_clause thy) axcls)
   310       ListPair.unzip (map (make_axiom_clause ctxt) axcls)
   299     (* FIXME: Should it read "extra_clauses" or "axiom_clauses" in the
   311     (* FIXME: Should it read "extra_clauses" or "axiom_clauses" in the
   300        "get_helper_clauses" call? *)
   312        "get_helper_clauses" call? *)
   301     val helper_clauses =
   313     val helper_clauses =
   302       get_helper_clauses thy is_FO full_types conjectures extra_clauses
   314       get_helper_clauses ctxt is_FO full_types conjectures extra_clauses
   303     val (supers', arity_clauses) = make_arity_clauses thy tycons supers
   315     val (supers', arity_clauses) = make_arity_clauses thy tycons supers
   304     val class_rel_clauses = make_class_rel_clauses thy subs supers'
   316     val class_rel_clauses = make_class_rel_clauses thy subs supers'
   305   in
   317   in
   306     (Vector.fromList clnames,
   318     (Vector.fromList clnames,
   307       (conjectures, axiom_clauses, extra_clauses, helper_clauses,
   319       (conjectures, axiom_clauses, extra_clauses, helper_clauses,
   365         ({subgoal, goal, relevance_override, axiom_clauses, filtered_clauses}
   377         ({subgoal, goal, relevance_override, axiom_clauses, filtered_clauses}
   366          : problem) =
   378          : problem) =
   367   let
   379   let
   368     (* get clauses and prepare them for writing *)
   380     (* get clauses and prepare them for writing *)
   369     val (ctxt, (_, th)) = goal;
   381     val (ctxt, (_, th)) = goal;
   370     val thy = ProofContext.theory_of ctxt;
   382     val thy = ProofContext.theory_of ctxt
   371     (* ### FIXME: (1) preprocessing for "if" etc. *)
   383     (* ### FIXME: (1) preprocessing for "if" etc. *)
   372     val (params, hyp_ts, concl_t) = strip_subgoal th subgoal
   384     val (params, hyp_ts, concl_t) = strip_subgoal th subgoal
   373     val the_filtered_clauses =
   385     val the_filtered_clauses =
   374       case filtered_clauses of
   386       case filtered_clauses of
   375         SOME fcls => fcls
   387         SOME fcls => fcls
   377                     relevance_convergence defs_relevant max_axiom_clauses
   389                     relevance_convergence defs_relevant max_axiom_clauses
   378                     (the_default prefers_theory_relevant theory_relevant)
   390                     (the_default prefers_theory_relevant theory_relevant)
   379                     relevance_override goal hyp_ts concl_t
   391                     relevance_override goal hyp_ts concl_t
   380     val the_axiom_clauses = axiom_clauses |> the_default the_filtered_clauses
   392     val the_axiom_clauses = axiom_clauses |> the_default the_filtered_clauses
   381     val (internal_thm_names, clauses) =
   393     val (internal_thm_names, clauses) =
   382       prepare_clauses full_types hyp_ts concl_t the_axiom_clauses
   394       prepare_clauses ctxt full_types hyp_ts concl_t the_axiom_clauses
   383                       the_filtered_clauses thy
   395                       the_filtered_clauses
   384 
   396 
   385     (* path to unique problem file *)
   397     (* path to unique problem file *)
   386     val the_dest_dir = if overlord then getenv "ISABELLE_HOME_USER"
   398     val the_dest_dir = if overlord then getenv "ISABELLE_HOME_USER"
   387                        else Config.get ctxt dest_dir;
   399                        else Config.get ctxt dest_dir;
   388     val the_problem_prefix = Config.get ctxt problem_prefix;
   400     val the_problem_prefix = Config.get ctxt problem_prefix;