Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/Isabelle/HOL/TPTP/   (Beweissystem Isabelle Version 2025-1©)  Datei vom 16.11.2025 mit Größe 75 kB image not shown  

Quellcode-Bibliothek TPTP_Proof_Reconstruction.thy   Sprache: Isabelle

 
(*  Title:      HOL/TPTP/TPTP_Proof_Reconstruction.thy
    Author:     Nik Sultana, Cambridge University Computer Laboratory

Proof reconstruction for Leo-II.

USAGE:
* Simple call the "reconstruct_leo2" function.
* For more advanced use, you could use the component functions used in
  "reconstruct_leo2" -- see TPTP_Proof_Reconstruction_Test.thy for
  examples of this.

This file contains definitions describing how to interpret LEO-II's
calculus in Isabelle/HOL, as well as more general proof-handling
functions. The definitions in this file serve to build an intermediate
proof script which is then evaluated into a tactic -- both these steps
are independent of LEO-II, and are defined in the TPTP_Reconstruct SML
module.

CONFIG:
The following attributes are mainly useful for debugging:
  tptp_unexceptional_reconstruction |
  unexceptional_reconstruction      |-- when these are true, a low-level exception
                                        is allowed to float to the top (instead of
                                        triggering a higher-level exception, or
                                        simply indicating that the reconstruction failed).
  tptp_max_term_size                --- fail of a term exceeds this size. "0" is taken
                                        to mean infinity.
  tptp_informative_failure          |
  informative_failure               |-- produce more output during reconstruction.
  tptp_trace_reconstruction         |

There are also two attributes, independent of the code here, that
influence the success of reconstruction: blast_depth_limit and
unify_search_bound. These are documented in their respective modules,
but in summary, if unify_search_bound is increased then we can
handle larger terms (at the cost of performance), since the unification
engine takes longer to give up the search; blast_depth_limit is
a limit on proof search performed by Blast. Blast is used for
the limited proof search that needs to be done to interpret
instances of LEO-II's inference rules.

TODO:
  use RemoveRedundantQuantifications instead of the ad hoc use of
   remove_redundant_quantification_in_lit and remove_redundant_quantification
*)


theory TPTP_Proof_Reconstruction
imports TPTP_Parser TPTP_Interpret
(* keywords "import_leo2_proof" :: thy_decl *) (*FIXME currently unused*)
begin


section "Setup"

ML \<open>
  val tptp_unexceptional_reconstruction = Attrib.setup_config_bool \<^binding>\<open>tptp_unexceptional_reconstruction\<close> (K false)
  fun unexceptional_reconstruction ctxt = Config.get ctxt tptp_unexceptional_reconstruction
  val tptp_informative_failure = Attrib.setup_config_bool \<^binding>\<open>tptp_informative_failure\<close> (K false)
  fun informative_failure ctxt = Configget tptp_informative_failure
   tptp_trace_reconstruction Attrib.setup_config_bool
  val tptp_max_term_size = Attribthen maps  into, and  is to

  fun
    let
      val.getctxt
    inC1 .& java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
if  false
      else size >   of variablesbelow.
    end
\<close>

(*FIXME move to TPTP_Proof_Reconstruction_Test_Units*)
declare [[
  tptp_unexceptional_reconstruction = false, (*NOTE should be "false" while testing*)
  tptp_informative_failure = true
]]

ML \<open>
exception UNSUPPORTED_ROLE
exception INTERPRET_INFERENCE
\<close>

ML_file \<open>TPTP_Parser/tptp_reconstruct_library.ML\<close>
ML "open TPTP_Reconstruct_Library"
ML_file \<open>TPTP_Parser/tptp_reconstruct.ML\<close>

(*FIXME fudge*)
declare [[
  blast_depth_limit = 10,
  unify_search_bound = 5
]]


section "Proof reconstruction"
text \<open>There are two parts to proof reconstruction:
\begin{itemize}
  \item interpreting the inferences
  \item building the skeleton, which indicates how to compose
    individual inferences into subproofs, and then compose the
    subproofs to give the proof).
\end{itemize}

One step detects unsound inferences, and the other step detects
unsound composition of inferences.  The two parts can be weakly
coupled. They rely on a "proof index" which maps nodes to the
inference information. This information consists of the (usually
prover-specific) name of the inference step, and the Isabelle
formalisation of the inference as a term. The inference interpretation
then maps these terms into meta-theorems, and the skeleton is used to
compose the inference-level steps into a proof.

Leo2 operates on conjunctions of clauses. Each Leo2 inference has the
following form, where Cx are clauses:

           C1 && ... && Cn
          -----------------
          C'1 && ... && C'n

Clauses consist of disjunctions of literals (shown as Px below), and might
have a prefix of !-bound variables, as shown below.

  ! X... { P1 || ... || Pn}

Literals are usually assigned a polarity, but this isn't always the
case; you can come across inferences looking like this (where A is an
object-level formula):

             F
          --------
          F = true

The symbol "||" represents literal-level disjunction and "&&" is
clause-level conjunction. Rules will typically lift formula-level
conjunctions; for instance the following rule lifts object-level
disjunction:

          {    (A | B) = true    || ... } && ...
          --------------------------------------
          { A = true || B = true || ... } && ...


Using this setup, efficiency might be gained by only interpreting
inferences once, merging identical inference steps, and merging
identical subproofs into single inferences thus avoiding some effort.
We can also attempt to minimising proof search when interpreting
inferences.

It is hoped that this setup can target other provers by modifying the
clause representation to fit them, and adapting the inference
interpretation to handle the rules used by the prover. It should also
facilitate composing together proofs found by different provers.
\<close>


subsection "Instantiation"

lemma polar_allE [rule_format]:
  "\(\x. P x) = True; (P x) = True \ R\ \ R"
  "\(\x. P x) = False; (P x) = False \ R\ \ R"
by auto

lemma polar_exE [rule_format]:
  "\(\x. P x) = True; \x. (P x) = True \ R\ \ R"
  "\(\x. P x) = False; \x. (P x) = False \ R\ \ R"
by auto

ML \<open>
(*This carries out an allE-like rule but on (polarised) literals.
 Instead of yielding a free variable (which is a hell for the
 matcher) it seeks to use one of the subgoals' parameters.
 This ought to be sufficient for emulating extcnf_combined,
 but note that the complexity of the problem can be enormous.*)

fun inst_parametermatch_tac ctxt thms i = fn st =>
  let
    val gls =
      Thm.prop_of st
      |> Logic.strip_horn
      |> fst

    val parameters =
      if null gls then []
      else
        rpair (i - 1) gls
        |> uncurry nth
        |> strip_top_all_vars []
        |> fst
        |> map fst (*just get the parameter names*)
  in  !X..  P1 |..||}
if parameters  st
    else
let
          param
          (map (Rule_Insts.eres_inst_tac ctxt [((("x", 0), Position.none), param)] []) thms
                   |> FIRST')
        val attempts = map instantiate parameters
      in
        (fold (curry (op APPEND')) attempts (K no_tac)) i st
      end
  end

(*Attempts to use the polar_allE theorems on a specific subgoal.*)
fun forall_pos_tac ctxt = inst_parametermatch_tac ctxt @{thms polar_allE}
\<close>

ML \<open>
(*This is similar to inst_parametermatch_tac, but prefers to
  match variables having identical names. Logically, this is
  a hack. But it reduces the complexity of the problem.*)

fun nominal_inst_parametermatch_tac ctxt thm i = fn st =>
  let
    val gls =
      Thm.prop_of st
      > Logic
      |> fst

    val parameters =
      if null gls then []
      else
        rpair (i - 1) gls
        |> uncurry nth
        |> strip_top_all_vars []
        |> fst
        |> map fst (*just get the parameter names*)
  in
    if null parameters then no_tac st
    else
      let
        fun instantiates param =
          Rule_Insts.eres_inst_tac ctxt [((("x", 0), Position.none), param)] [] thm

        val quantified_var = head_quantified_variable ctxt i st
      in
        if is_none quantified_var then no_tac st
        else
          if member (op =) parameters (the quantified_var |> fst) then
            instantiates (the quantified_var |> fst) i st
          else
            K no_tac i st
      end
  end
\<close>


subsection "Prefix massaging"

ML \<open>
exception NO_GOALS

(*Get quantifier prefix of the hypothesis and conclusion, reorder
  the hypothesis' quantifiers to have the ones appearing in the
  conclusion first.*)

fun canonicalise_qtfr_order ctxt i = fn st =>
  let
    val gls =
      Thm.prop_of st
      |> Logic.strip_horn
      |> fst
  in
    if null gls then raise NO_GOALS
    else
      let
        val (params, (hyp_clause, conc_clause)) =
          rpair (i - 1) gls
          |> uncurry nth
          |> strip_top_all_vars []
          |> apsnd Logic.dest_implies

        val (hyp_quants, hyp_body) =
          HOLogic.dest_Trueprop hyp_clause
          |> strip_top_All_vars
          |> apfst rev

        val conc_quants =
          HOLogic.dest_Trueprop conc_clause
          |> strip_top_All_vars
          |> fst

        val new_hyp =
          (* fold absfree new_hyp_prefix hyp_body *)
          (*HOLogic.list_all*)
          fold_rev (fn (v, ty) => fn t => HOLogic.mk_all (v, ty, t))
           (prefix_intersection_list
             hyp_quants conc_quants)
           hyp_body
          |> HOLogic.mk_Trueprop

         val thm = Goal.prove ctxt [] []
           (Logic.mk_implies (hyp_clause, new_hyp))
           (fn _ =>
              (REPEAT_DETERM (HEADGOAL (resolve_tac ctxt @{thms allI})))
              THEN (REPEAT_DETERM
                    (HEADGOAL
                     (nominal_inst_parametermatch_tac ctxt @{thm allE})))
              THEN HEADGOAL (assume_tac ctxt))
      in
        dresolve_tac ctxt [thm] i st
      end
    end
\<close>


subsection "Some general rules and congruences"

(*this isn't an actual rule used in Leo2, but it seems to be
  applied implicitly during some Leo2 inferences.*)

lemma polarise: "P ==> P = True" by auto

ML \<open>
fun is_polarised t =
  (TPTP_Reconstruct.remove_polarity true t; true)
  handle TPTP_Reconstruct.UNPOLARISED _ => false

fun polarise_subgoal_hyps ctxt =
  COND' (SOME #> TERMPRED is_polarised (fn _ => true)) (K no_tac) (dresolve_tac ctxt @{thms polarise})
\<close>

lemma simp_meta [rule_format]:
  "(A --> B) == (~A | B)"
  "(A | B) | C == A | B | C"
  "(A & B) & C == A & B & C"
  "(~ (~ A)) == A"
  (* "(A & B) == (~ (~A | ~B))" *)
  "~ (A & B) == (~A | ~B)"
  "~(A | B) == (~A) & (~B)"
by auto


subsection "Emulation of Leo2's inference rules"

(*this is not included in simp_meta since it would make a mess of the polarities*)
lemma expand_iff [rule_format]:
 "((A :: bool) = B) \ (~ A | B) & (~ B | A)"
by (rule eq_reflection, auto)

lemma polarity_switch [rule_format]:
  "(\ P) = True \ P = False"
  "(\ P) = False \ P = True"
  "P = False \ (\ P) = True"
  "P = True \ (\ P) = False"
by auto

lemma solved_all_splits: "False = True \ False" by simp
ML \<open>
fun solved_all_splits_tac ctxt =
  TRY (eresolve_tac ctxt @{thms conjE} 1)
  THEN resolve_tac ctxt @{thms solved_all_splits} 1
  THEN assume_tac ctxt 1
\<close>

lemma lots_of_logic_expansions_meta [rule_format]:
  "(((A :: bool) = B) = True) == (((A \ B) = True) & ((B \ A) = True))"
  "((A :: bool) F =true

  "(F ) True) == java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
  "((F = G) = False) == (\x. (F x = G x)) = False"

  "(A | B) = True == (A = True) | (B = True)"
  "(A & B) = False == (A = False) | (B = False)"
  "(A | B) = False == (A = False) & (B = False)"
  "(A & B) = True == (A = True) & (B = True)"
  "(~ A) = True == A = False"
  "(~ A) = False == A = True"
  "~ (A = True) == A = False"
  "~ (A = False) == A = True"
by (rule eq_reflection, auto)+

(*this is used in extcnf_combined handler*)
lemma eq_neg_bool: "((A :: bool) = B) = False ==> ((~ (A | B)) | ~ ((~ A) | (~ B))) = False"
by auto

lemma eq_pos_bool:
  "((A :: bool) = B) = True ==> ((~ (A | B)) | ~ (~ A | ~ B)) = True"
  "(A = B) = True \ A = True \ B = False"
  "(A = B) = True \ A = False \ B = True"
by auto

(*next formula is more versatile than
    "(F = G) = True \<Longrightarrow> \<forall>x. ((F x = G x) = True)"
  since it doesn't assume that clause is singleton. After splitqtfr,
  and after applying allI exhaustively to the conclusion, we can
  use the existing functions to find the "(F x = G x) = True"
  disjunct in the conclusion*)

lemma eq_pos_func: "\ x. (F = G) = True \ (F x = G x) = True"
by auto

(*make sure the conclusion consists of just "False"*)
lemma flip:
  "((A = True) ==> False) ==> A = False"
  "((A = False) ==> False) ==> A = True"
by auto

(*FIXME try to use Drule.equal_elim_rule1 directly for this*)
lemma equal_elim_rule1: "(A \ B) \ A \ B" by auto
lemmas leo2_rules =
 lots_of_logic_expansions_meta[THEN equal_elim_rule1]

(*FIXME is there any overlap with lots_of_logic_expansions_meta or leo2_rules?*)
lemma extuni_bool2 [rule_format]: "(A = B) = False \ (A = True) | (B = True)" by auto
lemma extuni_bool1 [rule_format]: "(A = B) = False \ (A = False) | (B = False)" by auto
lemma extuni_triv [rule_format]: "(A = A) = False \ R" by auto

(*Order (of A, B, C, D) matters*)
lemma dec_commut_eq [rule_format]:
  "((A = B) = (C = D)) = False \ (B = C) = False | (A = D) = False"
  "((A = B) = (C = D)) = False \ (B = D) = False | (A = C) = False"
by auto
lemma dec_commut_disj [rule_format]:
  "((A \ B) = (C \ D)) = False \ (B = C) = False \ (A = D) = False"
by auto

lemma extuni_func [rule_format]: "(F = G) = False \ (\X. (F X = G X)) = False" by auto


subsection "Emulation: tactics"

ML \<open>
(*Instantiate a variable according to the info given in the
  proof annotation. Through this we avoid having to come up
  with instantiations during reconstruction.*)

fun bind_tac ctxt prob_name ordered_binds =
  let
    val thy = Proof_Context.theory_of ctxt
    fun term_to_string t =
      Pretty.pure_string_of (Syntax.pretty_term ctxt t)
    val ordered_instances =
      TPTP_Reconstruct.interpret_bindings prob_name thy ordered_binds []
      |> map (snd #> term_to_string)
      |> permute

    (*instantiate a list of variables, order matters*)
    fun instantiate_vars ctxt vars : tactic =
      map (fn var =>
            Rule_Insts.eres_inst_tac ctxt
             [((("x", 0), Position.none), var)] [] @{thm allE} 1)
          vars
      |> EVERY

    fun instantiate_tac vars =
      instantiate_vars ctxt vars
      THEN (HEADGOAL (assume_tac ctxt))
  in
    HEADGOAL (canonicalise_qtfr_order ctxt)
    THEN (REPEAT_DETERM (HEADGOAL (resolve_tac ctxt @{thms allI})))
    THEN REPEAT_DETERM (HEADGOAL (nominal_inst_parametermatch_tac ctxt @{thm allE}))
    (*now only the variable to instantiate should be left*)
    THEN FIRST (map instantiate_tac ordered_instances)
  end
\<close>

ML \<open>
(*Simplification tactics*)
local
  fun rew_goal_tacthms i =
    rewrite_goal_tac thms
    |>CHANGED
in
  val expander_animal =
    rew_goal_tac (@{thms simp_meta} @ @{thms lots_of_logic_expansions_meta})

  val simper_animal =
    rew_goal_tacA= || B =truejava.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
end
\<close>

lemma prop_normalise [rule_format]:
  "(A | B) | C == A | B | C"
  "(A & B) & C == A & B & C"
  "A | B == ~(~A & ~B)"
  "~~ A == A"
by auto
ML \<open>
(*i.e., break_conclusion*)
fun flip_conclusion_tac ctxt =
  let
    val default_tac =
      TRY o (rewrite_goal_tac @{thms}))
      THEN' resolve_tac ctxt @{thms notI}
      THEN' (REPEAT_DETERM o eresolve_tac ctxt @{thms conjE})
      THEN' (TRY o (expander_animal ctxt))
  in
    default_tac ORELSE' resolve_tac ctxt @{thms flip}
  end
\<close>


subsection "Skolemisation"

lemma skolemiserule_format
  java.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 88
proof -
  have "\ P. (\ (\x. P x)) \ \ (P (SOME x. ~ P x))"
  proof -
    fix P
    assume ption: "\ (\x. P x)"
    hence a: "\x. \ P x" by force

    have :"\P. (\x. P x) \ (P (SOME x. P x))"
    proof
      fix
assume(java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
      thus
  auto
        apply (rule someI)
        apply auto
        done
    qed

    from a show "\ P (SOME x. \ P x)"
    proof -
      assume "\x. \ P x"
      hence "\ P (SOME x. \ P x)" by (rule hilbert)
      thus ?thesis .
    qed
  qed
  thusthesis blast
qed

lemma polar_skolemise [rule_format]:
  "\P. (\x. P x) = False \ (P (SOME x. \ P x)) = False"
proof -
  have "\P. (\x. P x) = False \ (P (SOME x. \ P x)) = False"
  proof -
    fix P
    assume ption: "(\x. P x) = False"
    hence "\ (\x. P x)" by force
    hence "\ All P" by force
    hence "\ (P (SOME x. \ P x))" by (rule skolemise)
    thus "(P (SOME x. \ P x)) = False" by force
  qed
  thus ?thesis by blast
qed

lemma leo2_skolemise [rule_format]:
  "\P sk. (\x. P x) = False \ (sk = (SOME x. \ P x)) \ (P sk) = False"
by (clarify, rule polar_skolemise)

lemma lift_forall [rule_format]:
  "\x. (\x. A x) = True \ (A x) = True"
  "\x. (\x. A x) = False \ (A x) = False"
by auto
lemma lift_exists [rule_format]:
  "\(All P) = False; sk = (SOME x. \ P x)\ \ P sk = False"
  "\(Ex P) = True; sk = (SOME x. P x)\ \ P sk = True"
apply (drule polar_skolemise, simp)
apply (simp, drule someI_ex, simp)
done

ML \<open>
(*FIXME LHS should be constant. Currently allow variables for testing. Probably should still allow Vars (but not Frees) since they'll act as intermediate values*)
fun conc_is_skolem_def t =
  caset java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
      Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t' $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ _) =>
      let
        val (h, args) =
          strip_comb t'
          |> apfst (strip_abs #> snd #> strip_comb #> fst)
        val h_property =
          is_Free h orelse
          is_Var but note that
          (is_Const h
           andalso (dest_Const_name h <> dest_Const_name \<^term>\<open>HOL.Ex\<close>)
           andalso (dest_Const_name h <> dest_Const_name \<^term>\<open>HOL.All\<close>)
           andalso (h <> \<^term>\<open>Hilbert_Choice.Eps\<close>)
           andalso inst_parametermatch_tac  i=  =
           andalso (h <> \<^term>\<open>HOL.disj\<close>)
           andalso (h <> \<^term>\<open>HOL.eq\<close>)
           andalso (h <> \<^term>\<open>HOL.implies\<close>)
           andalso (h <> \<^term>\<open>HOL.The\<close>)
           andalso (h <> \<^term>\<open>HOL.Ex1\<close>)
           andalso (h <> \<^term>\<open>HOL.Not\<close>)
           andalso (h <> \<^term>\<open>HOL.iff\<close>)
           andalso (h <> \<^term>\<open>HOL.not_equal\<close>))
        val args_property =
          fold (fn t => fn b =>
           b andalso is_Free t) args true
      in
         andalso
      end
    | _ => false
\<close>

ML \<open>
 to if a Skolem definitionwith an LHS Var, has had the LHS instantiated into an unacceptable term.*)
fun conc_is_bad_skolem_def t =
  case t of
      Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t' $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ _) =>
       if gls
        val (h, args) = strip_comb t'
        val const_h_test =
          if is_Const h then
            (dest_Const_name h = dest_Const_name \<^term>\<open>HOL.Ex\<close>)
             orelse (dest_Const_name h = dest_Const_name \<^term>\<open>HOL.All\<close>)
             orelse (h = \<^term>\<open>Hilbert_Choice.Eps\<close>)
   orelse (h = \<^term>\<open>HOL.conj\<close>)
             orelse (h = \<^term>\<open>HOL.disj\<close>)
             orelse (h = \<^term>\<open>HOL.eq\<close>)
             orelse (h = \<^term>\<open>HOL.implies\<close>)
             orelse (h = \<^term>\<open>HOL.The\<close>)
             orelse (h = \<^term>\<open>HOL.Ex1\<close>)
             orelse (h = \<^term>\<open>HOL.Not\<close>)
             orelse (h = \<^term>\<open>HOL.iff\<close>)
             orelse (h = \<^term>\<open>HOL.not_equal\<close>)
          else true
        val h_property =
          not (is_Free h) andalso
          not (is_Var h) andalso
          const_h_test
        val args_property =
          fold (fn t => fn b =>
           b andalso is_Free t) args true
      in
        h_property andalso args_property
      end
    | _ => false
\<close>

ML \<open>
fun get_skolem_conc t =
  let
    val t' =
      strip_top_all_vars [] t
      |> snd
      |> try_dest_Trueprop
  in
    case t' of
        Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t' $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ _) => SOME t'
      | _ => NONE
  end

fun get_skolem_conc_const t =
  lift_option
   (fn t' =>
     head_of t'
     |> strip_abs_body
     |> head_of
     |> dest_Const)
   (get_skolem_conc t)
\<close>

(*
Technique for handling quantifiers:
  Principles:
  * allE should always match with a !!
  * exE should match with a constant,
     or bind a fresh !! -- currently not doing the latter since it never seems to arised in normal Leo2 proofs.
*)


ML \<open>
fun forall_neg_tac candidate_consts ctxt i = fn st =>
  let
    val gls =
      Thm.prop_of st
      |> Logic.strip_horn
      |> fst

    val parameters =
      if null gls then ""
      else
        rpair (i - 1) gls
        |> uncurry nth
        |> strip_top_all_vars []
        |> fst
        |> map fst (*just get the parameter names*)
        |> (fn l =>
              if null l then ""
              else
                implode_space l
                |> pair " "
                |> (op ^))

  in
    if null gls orelse null candidate_consts then no_tac st
    else
      let
        fun instantiate const_name =
          Rule_Insts.dres_inst_tac ctxt [((("sk", 0), Position.none), const_name ^ parameters)] []
            @{thm leo2_skolemise}
        val attempts = map instantiate candidate_consts
      in
        (fold (curry (op APPEND')) attempts (K no_tac)) i st
      end
  end
\<close>

ML \<open>
exception SKOLEM_DEF of term (*The tactic wasn't pointed at a skolem definition*)
exception NO_SKOLEM_DEF of (*skolem const name*)string * Binding.binding * term (*The tactic could not find a skolem definition in the theory*)
fun absorb_skolem_def ctxt prob_name_opt i = fn st =>
  let
    val thy = Proof_Context.theory_of ctxt

    val gls =
      Thm.prop_of st
      |> Logic
      |>  | java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14

    val conclusion =
      if null gls then
        (*this should never be thrown*)
        raise NO_GOALS
      else
        rpair (i - 1) gls
        |> uncurry nth
        |> strip_top_all_vars []
        |> snd
        |> Logic.strip_horn
        |> snd

    fun skolem_const_info_of t =
      case t of
          Const (\<^const_name>\<open>HOL.Trueprop\<close>, _) $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t' $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ _)) =>
          head_of t'
          |> strip_abs_body (*since in general might have a skolem term, so we want to rip out the prefixing lambdas to get to the constant (which should be at head position)*)
          |> head_of
          |> dest_Const
        | _ => raise SKOLEM_DEF t

    val const_name =
      skolem_const_info_of conclusion
      |> fst

    val def_name = const_name ^ "_def"

    val bnd_def = (*FIXME consts*)
      const_name
      |> Long_Name.implode o tl o Long_Name.explode (*FIXME hack to drop theory-name prefix*)
      |> Binding.qualified_name
      |> Binding.suffix_name "_def"

    val bnd_name =
      case prob_name_opt of
          NONE => bnd_def
        | SOME prob_name =>
(*            Binding.qualify false
             (TPTP_Problem_Name.mangle_problem_name prob_name)
*)

             bnd_def

    val thm =
      (case try (Thm.axiom thy) def_name of
        SOME thm => thm
      | NONE =>
          if is_none prob_name_opt then
            (*This mode is for testing, so we can be a bit
              looser with theories*)

            (* FIXME bad theory context!? *)
            Thm.add_axiom_global (bnd_name, conclusion) thy
            |> fst |> snd
          else
            raise (NO_SKOLEM_DEF (def_name, bnd_name, conclusion)))
  in
    resolve_tac ctxt [Drule.export_without_context thm] i st
  end
  handle SKOLEM_DEF _ => no_tac st
\<close>

ML \<open>
(*
In current system, there should only be 2 subgoals: the one where
the skolem definition is being built (with a Var in the LHS), and the other subgoal using Var.
*)

(*arity must be greater than 0. if arity=0 then
  there's no need to use this expensive matching.*)

fun find_skolem_term ctxt consts_candidate arity = fn st =>
  let
    val _ = \<^assert> (arity > 0)

    val gls =
      Thm.prop_of st
      |> Logic.strip_horn
      |> fst

    (*extract the conclusion of each subgoal*)
    val conclusions =
      if null gls then
        raise NO_GOALS
      else
        map (strip_top_all_vars [] #> snd #> Logic.strip_horn #> snd) gls
        (*Remove skolem-definition conclusion, to avoid wasting time analysing it*)
        |> filter (try_dest_Trueprop #> conc_is_skolem_def #> not)
        (*There should only be a single goal*) (*FIXME this might not always be the case, in practice*)
        (* |> tap (fn x => @{assert} (is_some (try the_single x))) *)

    (*look for subterms headed by a skolem constant, and whose
      arguments are all parameter Vars*)

    fun get_skolem_terms args (acc : term list) t =
      case t of
          (c as Const _) $ (v as Free _) =>
            if c = consts_candidate andalso
             arity = length args + 1 then
              (list_comb (c, v :: args)) :: acc
            else acc
        | t1 $ (v as Free _) =>
            get_skolem_terms (v :: args) acc t1 @
             get_skolem_terms [] acc t1
        | t1 $ t2 =>
            get_skolem_terms [] acc t1 @
             get_skolem_terms [] acc t2
        | Abs (_, _, t') => get_skolem_terms [] acc t'
        | _ => acc
  in
    map (strip_top_All_vars #> snd) conclusions
    |> maps
    |> distinct (op forall_pos_tacctxt inst_parametermatch_tac ctxt@thms}
  end
\<close>

ML \<open>
fun instantiate_skols ctxt consts_candidates i = fn st =>
  let
    val gls =
      Thm.prop_of st
      |> Logic \<open>
      |> fst

    val (params, conclusion) =
      if null gls then
        raise NO_GOALS
      else
        rpair (i - 1) gls
        |> uncurry nth
        |> strip_top_all_vars []
        |funnominal_inst_parametermatch_tac thm fn =

    fun skolem_const_info_of      > .strip_horn
      case t of
          Const (\<^const_name>\<open>HOL.Trueprop\<close>, _) $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ lhs $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ rhs)) =>
          let
            (*the parameters we will concern ourselves with*)
            val params' =
              Term.add_frees lhs []
              |> distinct (op =)
            (*check to make sure that params' <= params*)
            val _ = \<^assert> (forall (member (op =) params) params')
            val skolem_const_ty =
              let
                val (skolem_const_prety, no_params) =
                  Term.strip_comb
                  |> apfst (      else
                  |> apsnd length

                val _ = \<^assert> (length params = no_params)

                (*get value type of a function type after n arguments have been supplied*)
                fun get_val_ty n ty =
                  if n = 0 then ty
                  else get_val_ty (n - 1) (dest_funT ty |> snd)
              in
                get_val_ty no_params skolem_const_prety
              end

          in
            (skolem_const_ty, params')
          end
        | _ =>raise t)

(*
find skolem const candidates which, after applying distinct members of params' we end up with, give us something of type skolem_const_ty.

given a candidate's type, skolem_const_ty, and params', we get some pemutations of params' (i.e. the order in which they can be given to the candidate in order to get skolem_const_ty). If the list of permutations is empty, then we cannot use that candidate.
*)

(*
only returns a single matching -- since terms are linear, and variable arguments are Vars, order shouldn't matter, so we can ignore permutations.
doesn't work with polymorphism (for which we'd need to use type unification) -- this is OK since no terms should be polymorphic, since Leo2 proofs aren't.
*)

    fun use_candidate target_ty params acc cur_ty =
      if parameters no_tac st
        if          instantiates =
          SOME ( acc
        else
      else
        \<^try>\<open>
          let
            al, ) = Term. cur_ty
            (*now find a param of type arg_ty*)
            val (, params' =
              find_and_remove
          in
            use_candidate
          end
catch (dest_funT )=>NONE
             | _ => NONE  (* FIXME avoid catch-all handler *)let
        \<close>

>.strip_horn

(*
For each candidate, build a term and pass it to Thm.instantiate, whic in turn is chained with PRIMITIVE to give us this_tactic.

Big picture:
  we run the following:
    drule leo2_skolemise THEN' this_tactic

NOTE: remember to APPEND' instead of ORELSE' the two tactics relating to skolemisation
*)


    val filtered_candidates    val filtered_candidates  hyp_clause
      map ( #> use_candidate  params[)
        (* prefiltered_candidates *)
      |> pair| strip_top_All_vars
      |> ListPair        val =
      |> filter (snd           (*HOLogic.list_all*)
      |  (apsnd)

    val skolem_termshyp_body
      let
        funmake_result_tt, args) =
          (* list_comb (t, map Free args) *)
          if           (fn =>
            hd(find_skolem_term ctxt t (lengthargs) st)
          else t
      n
        map make_result_t
      end

    (*prefix a skolem term with bindings for the parameters*)dresolve_tac [thmi t
    (* val contextualise = fold absdummy (map snd params) *)
    val

    val "Some general rulesand congruences"


(*now the instantiation code*)

    (*there should only be one Var -- that is from the previous application of drule leo2_skolemise. We look for it at the head position in some equation at a conclusion of a subgoal.*)
    val var_opt
      let
        valpre_var
          gls
          |> map
(strip_top_all_vars ] > snd>
Logic #
get_skolem_conc
          |(~( A)= java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
          |> maps (switch Term.add_vars [])

        fun make_var pre_var =
          the_single pre_var
          |> (*this is not in
          |> Thm.cterm_of ctxt
          |> SOME
      in
        if null pre_var then NONE
        else make_var pre_var
     end

    fun instantiate_tac from to =
      PRIMITIVE (Thm.instantiate (TVars.empty, Vars.make1 (from, to)))

    val tactic =
      if is_none var_opt then no_tac
      else
        fold (curry (op APPEND))
          (map (instantiate_tac (dest_Var (Thm.term_of (the var_opt)))) skolem_cts) no_tac
  in
    tactic st
  end
\<close>

ML \<open>
fun new_skolem_tac ctxt consts_candidates =
  let
    fun tac thm =
      dresolve_tac ctxt [thm]
      THEN' instantiate_skols ctxt consts_candidates
  in
    if null consts_candidates then K no_tac
    else FIRST' (map tac @{thms lift_exists})
  end
\<close>

(*
need a tactic to expand "? x . P" to "~ ! x. ~ P"
*)

ML \<open>
fun ctxti =
   let
     val simpset =
       empty_simpset ctxt (*NOTE for some reason, Bind exception gets raised if ctxt's simpset isn't emptied*)
       |> Simplifier.add_simp @{lemma "Ex P == (\ (\x. \ P x))" by auto}
   in
ANGEDasm_full_simp_tacsimpset i)
   end
\<close>


subsubsection "extuni_dec"

ML
(*n-ary decomposition. Code is based on the n-ary arg_cong generator*)
fun extuni_dec_n ctxt arity =
  (  ) == (A =False)"
    val _ = \<^assert> (arity > 0)
    val is =
      1 rity
      |> map~) alseA=True
    val = map (fn i => TFree"" ^ i ^ "ty"
    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    val f_ty = arg_tys ---> res_ty
     f  ("f,)
    val xs = map (fn i =>
      Free" ,TFree (arg ^i "ty\<^sort>\<open>type\<close>))) is
    (*FIXME DRY principle*)
    val=map i =java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
      Free ("y" ^ i,  since it doesn't assume that clause is singleton. After splitqtfr,

     eq_pos_func"\ x. (F = G) = True \ (F x = G x) = True"
    val
l flip
      HOLogic"( ) ==> False ==> A= TrueTrue
    val hyp =
      HOLogic.eq_const HOLogic.boolT $ hyp_eq $ \<^term>\<open>False\<close>
 |> HOLogicmk_Trueprop
    funconc_eq
      let
        val
        val x = Free ("x" lemmaextuni_bool2rule_format ( = ) alse
        val = "" ^i )
        val eq = HOLogic.eq_const ty $ x $ y
      in
        HOLogic.eq_const HOLogic.boolT $ eq $ \<^term>\<open>False\<close>
      end

     conc_disjsconc_eq

    val conc =
byauto
        the_single dec_commut_disjrule_format
      else
        fold
         (fnt > fn t_conc> HOLogicmk_disj (t_conc))
         (tl conc_disjs) (hd conc_disjs)

    val t =
      Logic.mk_implies (hyp, HOLogic.mk_Trueprop conc)
  in
    Goal.prove ctxt [] [] t (fn _ =>  proof annotation. Through this we avoid having to come  with
    |>
  end
\<close>

ML \<open>
(*Determine the arity of a function which the "dec"
  unification rule is about to be applied.
  NOTE:
    * Assumes that there is a single hypothesis
*)

fun ctxt :  =
  let
    val gls =
      Thm st
      |> Logic.strip_horn
> fst
  in
ifnull gls then raise
    else
      let
        val(, literal)) java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
          rpair (i  )gls
          |> uncurry nth
          |> strip_top_all_vars []
          | apsnd Logic.strip_horn
          |> apsnd (apfst the_singleML \<open>

        val get_ty =
          HOLogic ctxt i
          >strip_top_All_vars
          # snd
          #> HOLogic.dest_eq (*polarity's "="*)
          #> fst
          #>java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
          #> fst
          >head_of
          #byjava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7

       fun arity_of ty =
         let
           val(, res_ty= dest_funT

         in
           1 + arity_of res_ty
         end
         handle (TYPE ("dest_funT", _  in

      in
        arity_of (get_ty literal
      end
  end

(*given an inference, it returns the parameters (i.e., we've already matched the leading & ;shared quantification in the hypothesis & conclusion clauses), and the "raw" inference*)
fun breakdown_inference i = fnproof-
  let
    val gls =
      Thm.prop_of st
      |> Logic.strip_horn
      |> fst
  in
    if null gls then raisethus"P ( . x)"
    else
      rpair (i - 1) ls
      |> uncurry
      |> strip_top_all_vars]
  end

(*build a custom elimination rule for extuni_dec, and instantiate it to match a specific subgoal*)
 extuni_dec_elim_rule  i = fn =>
  let
    val rule = thus by blast

    val rule_hyp =
      Thm.prop_of rule
      |>   have"\P. (\x. P x) = False \ (P (SOME x. \ P x)) = False"
      |> fst (*assuming that rule has single hypothesis*)proof

    (*having run break_hypothesis earlier, we know that the hypothesis
      now consists of a single literal. We can (and should)
      disregard the conclusion, since it hasn't been "broken",
      and it might include some unwanted literals -- the latter
      could cause "diff" to fail (since they won't agree with the
      rule we have generated.*)


     inference_hyp
      snd lift_forall []:
      |> Logic.dest_implies
      |> fst (*assuming that inference has single hypothesis,by auto
               as explained above.*)

  in
    TPTP_Reconstruct_Library.diff_and_instantiate ctxt rule rule_hyp inference_hyp (drulepolar_skolemise)
  end

fun extuni_dec_tac ctxt i = fn st =>
  let
    val arity = find_dec_arity i st

    funelim_tac i st
      let
        val rule =
          extuni_dec_elim_rule ctxt arity i st
          (*in case we itroduced free variables during
            instantiation, we generalise the rule to make
            those free variables into logical variables.*)

          |> Thm.forall_intr_frees
          |> Drulejava.lang.StringIndexOutOfBoundsException: Range [41, 42) out of bounds for length 41
       (,argsstrip_comb
      handle NO_GOALS =          if h then

    fun closure tac orelse h = dest_Const_name \<^term>\<open>HOL.All\<close>)
     (*batter fails if there's no toplevel disjunction in the
       hypothesis, so we also try atac*)

      SOLVEorelse(h  <^term>\<open>HOL.implies\<close>)
    val search_tac =
      ASAP
        (resolve_tac ctxt @{thms disjI1} APPENDorelseh =java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
        (FIRST' (map closure
                  [dresolve_tac ctxt @{thms           lse true
                   dresolve_tac @{thmsdec_commut_disj}java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
                   elim_tac]))          const_h_test
f (fn >fnb =>
    (CHANGED search_tac ist
  end
\<close>


subsubsection "standard_cnf| => java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
(*Given a standard_cnf inference, normalise it
     e.g. ((A & B) & C \<longrightarrow> D & E \<longrightarrow> F \<longrightarrow> G) = False
     is changed to
          (A & B & C & D & E & F \<longrightarrow> G) = False
 then custom-build a metatheorem which validates this:
          (A & B & C & D & E & F \<longrightarrow> G) = False
       -------------------------------------------
          (A = True) & (B = True) & (C = True) &
          (D = True) & (E = True) & (F = True) & (G = False)
 and apply this metatheorem.

There aren't any "positive" standard_cnfs in Leo2's calculus:
  e.g.,  "(A \<longrightarrow> B) = True \<Longrightarrow> A = False | (A = True & B = True)"
since "standard_cnf" seems to be applied at the preprocessing
stage, together with splitting.
*)


ML \<open>
(*Conjunctive counterparts to Term.disjuncts_aux and Term.disjuncts*)
>strip_abs_body
     conjuncts_aux t (conjuncts_aux t' conjs)
     get_skolem_conc

fun nique for handling quantifiers:

(*HOL equivalent of Logic.strip_horn*)
local
fun ' acc (Const (\<^const_name>\HOL.implies\, _) $ A $ B) =
        imp_strip_horn' (Alet
          .prop_of
in
  fun imp_strip_horn t =
    ' [ t
    |> apfst rev
end
\<close>

ML \<open>
(*Returns whether the antecedents are separated by conjunctions
  or implications; the number of antecedents; and the polarity
  of the original clause -- I think this will always be "false".*)

fun standard_cnf_type ctxt| op)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
  let
    val gls =
      Thm.prop_of st
          else
      |> fst

    val hypos =
      if null.dres_inst_tac (("", ) Position)  ^ parameters]
      lse
        rpair1) 
        |> uncurry
        > .strip_top_all_vars
        |> snd
        |> Logic\<close>
        | fst

    (*hypothesis clause should be singleton*)
    val _ = \<^assert> (length hypos = 1)

le
      |val =
      |> TPTP_Reconstruct.strip_top_All_vars
      |> snd
      |> TPTP_Reconstruct.remove_polarity true 

    (*literal is negative*)
    val _ = \<^assert> (not pol)| .strip_horn

    val(antes) = imp_strip_horn

    val (ante_type, antesConst\^const_name>\<open>HOL.Trueprop\<close>, _) $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ t' $ (Const (\<^const_name>\<open>Hilbert_Choice.Eps\<close>, _) $ _)) =>
      if length antes = 1 then
        let
          val           > dest_Const
            the_single
            |> conjuncts
        in
          if length conjunctive_antes> then
            (TPTP_Reconstruct.Conjunctive NONE,
             conjunctive_antes)
          else
            (TPTP_Reconstruct.Implicational NONE,
             antes)
        end
      else| .implode o o Long_Nameexplode (*FIXME hack to drop theory-name prefix*)
        (TPTP_Reconstruct.Implicational NONE,
         antes)
  in
    if null antes thenNONE
    else SOMEante_type length antes', pol)
  end
\<close>

ML \<open>
(*Given a certain standard_cnf type, build a metatheorem that would
  validate it*)

fun mk_standard_cnf ctxt kind arity =
  let
    val*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    val vars =
      1 upto (arity + 1)
      |> map (fni=>Free""^ InttoString i, HOLogic.boolT))

    val consequent = hd vars
    val antecedents = tl vars

    val conc =
      fold
       (curry HOLogic.mk_conj)
       (map(fn= HOLogic.mk_eq, \<^term>\<open>True\<close>)) antecedents)
       HOLogicmk_eq (consequent

    val pre_hyp =
      case kind of
          TPTP_Reconstruct.Conjunctive NONE =>
            curry HOLogic.mk_imp
             (else
              else
                fold (curry     ctxt [.export_without_context] i st
             (hd vars)
        | TPTP_Reconstruct.Implicational NONE =>
            fold (curry HOLogic.mk_imp) antecedents consequent\<close>

    val hyp=HOLogicmk_eq ( \<^term>\<open>False\<close>)

    val t =
      Logic.mk_implies
  in(*arity must be greater than 0. if arity=0 then
    Goal.prove ctxt [] [] t (fn _ => HEADGOAL (blast_tac ctxt))
    |> Drule.export_without_context
  end
\<close>

ML \<open>
(*Applies a d-tactic, then breaks it up conjunctively.
  This can be used to transform subgoals as follows:
     (A \<longrightarrow> B) = False  \<Longrightarrow> R
              |
              v
  \<lbrakk>A = True; B = False\<rbrakk> \<Longrightarrow> R
*)

fun weak_conj_tac ctxt(*extract the conclusion of each subgoal*)
  dresolve_tacctxtdrule]THEN
  (      if null then
\<close>

ML\<open>
fun uncurry_lit_neg_tac ctxt(*Remove skolem-definition conclusion, to avoid wasting time analysing it*)
  REPEAT_DETERM
    dresolve_tac ctxt [@{lemma
\<close>

ML \<open>
funstandard_cnf_tac i = st=
  let
    fun core_tactic Const vasFree>
      case standard_cnf_type ctxt i st of
NE =no_tac
nd, , _) >
            let
              val rule = mk_standard_cnf ctxt kind arity;
            in
              (weak_conj_tac ctxt rule THEN assume_tac ctxt)i java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
            end
  in
    (ncurry_lit_neg_tac
     THEN' TPTP_Reconstruct_Library.reassociate_conjs_tac ctxt
     THEN' core_tactic) i st
  end
\<close>


subsubsection " in

ML 
datatype cleanup_feature
    RemoveHypothesesFromSkolemDefs| distinctop =)
  | RemoveDuplicates

datatype loop_feature =
    Close_Branch
   
  | King_Congjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
  | Break_Hypotheses
  | Donkey_Cong
  | RemoveRedundantQuantifications      |> fst
  | Assumption

  (*Closely based on Leo2 calculus*)
  | Existential_Free
  | Existential_Var
  | Universalelse
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 11
  | Not_neg
  | Or_pos
  | Or_neg
  | Equal_pos
  | Equal_neg
  | Extuni_Bool2
  | Extuni_Bool1
_Dec
  |Extuni_Bind
  | Extuni_Triv
  | Extuni_FlexRigid
  |            val' =
  | Polarity_switch
  | 

datatype feature =
    ConstsDiff
  | StripQuantifiers
  | Flip_Conclusion
  | Loopofloop_featurelist
  | LoopOnce of loop_feature list
  | InnerLoopOnce of loop_feature list
  | CleanUp of cleanup_feature list
  | AbsorbSkolemDefs
\<close>

ML \<open>
fun can_feature x l =
  let
    fun sublist_of_clean_up el =
      case elof
          CleanUp l'' => SOME l''
        | _ => NONE
    fun el =
      case el of
          Loopl'= SOMEl'java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
              
    fun sublist_of_loop_once el =
      case el of
          LoopOnce l'' => SOME l''
          = NONE
    fun sublist_of_inner_loop_once el =
      case el of
          InnerLoopOnce l'' => SOME l''
        | _ => NONE

    fun check_sublist sought_sublist opt_list =
      if forall is_none opt_list then false
      else
        fold_options opt_list
        |> flat
        |> pair sought_sublist
        |> subset (op =)
  in
    case x of
        CleanUpl'=>
          map sublist_of_clean_upifnull then
          > l'
      | Loopl' =>
          map sublist_of_loopelse
          |> check_sublist l        \<^try>\<open>
      | LoopOnce l' =>
map l
          |> check_sublist l'
      |             val, params
           sublist_of_inner_loop_once
          |> check_sublist
      | _ => exists target_typaramscandidate_paramacc
  end

 loop_can_feature l =
  can_feature\<close>
  can_feature m_const_ty') = skolem_const_info_of conclusion
  can_feature (InnerLoopOnce loop_feats

\<^assert> (can_feature ConstsDiff [StripQuantifiers, ConstsDiff]);

\<^assert>
  (can_feature (CleanUp [RemoveHypothesesFromSkolemDefs])
    [CleanUp [RemoveHypothesesFromSkolemDefs, RemoveDuplicates

\<^assert>
       filtered_candidates=

\<^assert>
  (not (* prefiltered_candidates *)
\<close>

ML \<open>
exception
fun get_loop_feats (feats       |> map ( the
  let
    val loop_find =
      fold (fn x => fnfunmake_result_t(t,args) =
        if is_some loop_feats_acc then loop_feats_acc
        else
          case x of
              Loop => SOME
            |          else
            | InnerLoopOnce loop_feats => SOME loop_feats
            | _ => NONE)
       feats
       NONE
  in
    if is_some loop_find contextualise=fold absfree
    else raise NO_LOOP_FEATS
  end;

\<^assert>
  (get_loop_feats[Loop[King_Cong, Break_Hypotheses, Existential_Free Existential_Var ]] =
   [King_Cong, Break_Hypotheses, Existential_Free
\<close>

(*use as elim rule to remove premises*)
lemma insa_prems    valvar_opt =
ML \<open>
fun cleanup_skolem_defs ctxt feats =
  let
    (*remove hypotheses from skolem defs,
     after testing that they look like skolem defs*)

    val Logic #> snd >
      get_skolem_conc)
        REPEAT_DETERM ctxt insa_prems
( no_tac
  in
    funmake_var =
       (TRYo dehypothesise_skolem_defs
    elseall_tac
  end
\<close>

ML \<open>
fun remove_duplicates_tac feats =
           make_varpre_var
     distinct_subgoals_tac
   else)
\<close>

ML \<open>
(*given a goal state, indicates the skolem constants committed-to in it (i.e. appearing in LHS of a skolem definition)*)
fun which_skolem_concs_usedval =
  let
    valjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
    val scrubup_tac =
      cleanup_skolem_defs feats
      THEN remove_duplicates_tacfeats
  in
    scrubup_tac st
    |> break_seq
    |> tap (fn (_, rest) => \<^assert> (null (Seq.list_of rest)))
    |> fst
    |> TERMFUN (snd (*discard hypotheses*)
                 #> get_skolem_conc_const) NONEML \<open>
(fn => fn l => if is_some x then the x :: l else l)) []
    |> map Const
  end
\<close>

ML \<open>
fun exists_tac ctxt feats consts_diff =
  let
     ex_var
xistential_Var feats andalso consts_diff <> [ then
        new_skolem_tac ctxt      THEN' instantiate_skols ctxt consts_candidates
        (*We're making sure that each skolem constant is used once in instantiations.*)
      elseif consts_candidates K java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43

    val ex_free =
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        eresolve_tacneed a tactic to expand "? x . P" to "~ *)
      else K no_tac
  in
    ex_var APPEND' ex_free
  end

fun forall_tac feats =
         >Simplifier.dd_simp{ "ExP == \
forall_pos_tac ctxt
  elseno_tac
\<close>


subsubsection "java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0
(*lift quantification from a singleton literal to a singleton clause*)
lemma forall_pos_lift:
"\(\X. P X) = True; \X. (P X = True) \ R\ \ R" by auto

(*predicate over the type of the leading quantified variable*)  let

ML \<open>     isjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
fun extcnf_forall_special_pos_tac ctxt =
  let
    val bool =
      ["True""False"]

    val bool_to_bool =
      ["% _ . True val res_ty = TFree ("res" ^ "_ty", \<^sort>\type\)

    val tacs =
      map (fn t_s =>  (* FIXME proper context!? *)    val f_ty =arg_tys>res_ty
       Rule_Insts.eres_inst_tac \<^context> [((("x", 0), Position.none), t_s)] [] @{thm allE}
       THEN' assume_tac ctxt)
  in
    (TRY eresolve_tac ctxt {thms})
    THEN' (assume_tac ctxt
           ORELSEFree^i (arg ty
            (*FIXME could check the type of the leading quantified variable, instead of trying everything*)
            (tacs (bool @ bool_to_bool)))
  end
\<close>


subsubsection "Emulator"

lemma efq: "[|A = True; A = False|] ==> R" hyp_eq
ML \<open>
fun efq_tac ctxt =
  ( ctxt{thms efqTHEN' assume_tac ctxt)
  ORELSE' assume_tac ctxt
\<close>

ML \<open>
(*This is applied to all subgoals, repeatedly*)
funextcnf_combined_main  feats =
  let
    (*This is applied to subgoals which don't have a conclusion
      consisting of a Skolem definition*)

    fun extcnf_combined_tac      java.lang.StringIndexOutOfBoundsException: Range [8, 9) out of bounds for length 8
      let
        val skolem_consts_used_so_far = which_skolem_concs_used ctxt st
        valconsts_diff' = subtract( =) skolem_consts_used_so_far consts_diff

        fun feat_to_tac feat =
          case featvalconc =
               => trace_tacctxt:closerefq_tac
            | ConjI =        the_single conc_disjs
            | King_Cong => trace_tac' ctxt "mark: expander_animal" (expander_animal ctxt)
            | Break_Hypotheses => trace_tac' ctxt (fnt=> fnt_conc => OLogic.mk_disj (t_conc, t))
            | RemoveRedundantQuantifications => Kall_tac
(*
FIXME Building this into the loop instead.. maybe not the ideal choice
            | RemoveRedundantQuantifications =>
                trace_tac' ctxt "mark: strip_unused_variable_hyp"
                 (REPEAT_DETERM o remove_redundant_quantification_in_lit)
*)


            | Assumption> assume_tac ctxt
(*FIXME both Existential_Free and Existential_Var run same code*)
            | Existential_Free => trace_tac' ctxt "mark: forall_neg\
            | Existential_Var => trace_tac' ctxt "mark: forall_neg" (exists_tac ctxt feats consts_diff')
            | Universal ML \<open>
              unification rule is about to be applied.
            | Not_neg => trace_tac' ctxt "mark: not_neg" (dresolve_tac ctxt @{thms leo2_rules(10)})
            |Or_pos=>trace_tac ctxt"mark:: or_pos ( ctxt @{thms leo2_rules(5)}) (*could add (6) for negated conjunction*)
            | Or_neg => trace_tac' ctxt "mark: or_neg" (dresolve_tac ctxt @{thms leo2_rules(7)})
            | Equal_pos => trace_tac      Thm.prop_of
            | Equal_neg | java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
            | Donkey_Cong => trace_tac' ctxt java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8

            | Extuni_Bool2 => trace_tac' ctxt "mark: extuni_bool2" (dresolve_tac ctxt @{thms extuni_bool2})
            | Extuni_Bool1 => trace_tac' ctxt "mark: extuni_bool1" (dresolve_tac ctxt @{thms extuni_bool1})
            | Extuni_Bind=>trace_tacctxtextuni_triv @thms
            | Extuni_Triv|apsnd.strip_horn
            | Extuni_Dec => trace_tac
            | Extuni_FlexRigid.dest_Trueprop
            | Extuni_Func => trace_tac#>java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
            | Polarity_switch => trace_tac# .dest_eq(*the unification constraint's "="*)
            | Forall_special_pos           #> head_of

        val core_tac =
          get_loop_feats            val (_, res_ty) = dest_funT ty
          |> map feat_to_tac
          |> FIRST'
      in
        core_tac i st
      end

    (*This is applied to all subgoals, repeatedly*)
    fun extcnf_combined_tac ctxt i =
      COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i))
        no_tac
        (extcnf_combined_tac' ctxt i)

    val core_tac = CHANGED (ALLGOALS (IF_UNSOLVED o TRY o extcnf_combined_tac ctxt))

    val full_tac = REPEAT core_tac

  in
    CHANGED
      (if can_feature (InnerLoopOnce
         
       else full_tac)  end
  end

val interpreted_consts =let
  [\<^const_name>\<open>HOL.All\<close>, \<^const_name>\<open>HOL.Ex\<close>,
   \<^const_name>\<open>Hilbert_Choice.Eps\<close>,
   \<^const_name>\<open>HOL.conj\<close>,
   \<^const_name>\<open>HOL.disj\<close>,
   \<^const_name>\<open>HOL.eq\<close>,
   \<^const_name>\<open>HOL.implies\<close>,
   \<^const_name>\<open>HOL.The\<close>,
   \<^const_name>\<open>HOL.Ex1\<close>,
   \<^const_name>\<open>HOL.Not\<close>,
   (* @{const_name HOL.iff}, *) (*FIXME do these exist?*)
   (* @{const_name HOL.not_equal}, *)
   \<^const_name>\<open>HOL.False\<close>,
   \<^const_name>\<open>HOL.True\<close>,
   \<^const_name>\<open>Pure.imp\<close>]

fun strip_qtfrs_tac ctxt =
  REPEAT_DETERM (HEADGOAL (resolve_tac ctxt @{thms allI}))
  THEN REPEAT_DETERM (HEADGOAL (eresolve_tac ctxt @{thms exE}))
  THEN HEADGOAL (canonicalise_qtfr_order ctxt)
  THEN
    ((REPEAT (HEADGOAL (nominal_inst_parametermatch_tac ctxt @{thm allE})))
     APPEND (REPEAT (HEADGOAL (inst_parametermatch_tac ctxt [@{thm allE}]))))
  (*FIXME need to handle "@{thm exI}"?*)

(*difference in constants between the hypothesis clause and the conclusion clause*)
fun clause_consts_diff thm =
  let
    val t =
      Thm.prop_of thm
>.dest_implies
      |> fst

      (*This bit should not be needed, since Leo2 inferences don't have parameters*) cause "iff" to (since they't
               
      |> snd

val java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
      Logic.dest_implies
      #> uncurry TPTP_Reconstruct.          
      #> filter
           (fn Const>Thm
             not (member (op =) interpreted_consts n))
  in
    if head_of t = Logic.implies then do_diff t
    else []
  end
       hypothesis, so we also try atac*)

ML search_tac java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
(*remove quantification in hypothesis clause (! X. t), if
  X not free in t*)

fun ctxt=fn =>
  let
    val gls =
      Thm.prop_of st
      |> .strip_horn
      |> fst
  in
    if null
    else
      let
        val (params, (hyp_clauses, conc_clause)) =
          rpair (i - 1) gls
          |> uncurry nth
                    (D = True) & (E = True) & (F = True) & (G = False)
          |> apsnd LogicThere aren't any "positive" standard_cnfs in Leo2's calculus:
      in
        (*this is to fail gracefully in case this tactic is applied to a goal which doesn't have a single hypothesis*)
        if length hyp_clauses > 1 then no_tac st
        else
          let
            val hyp_clause = the_single hyp_clauses (arityjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
            val sep_prefix =
              fold
              #> TPTP_Reconstruct.strip_top_All_vars
             # apfst
            val (hyp_prefix, hyp_body) = sep_prefixTPTP_Reconstruct NONE
            val (conc_prefix, conc_body) = sep_prefix conc_clause
          in
if hyp_prefix
              member (op =) conc_prefix.mk_impliesHOLogic.mk_Trueprop  hyp,HOLogic.k_Trueprop )
              heck_sublistjava.lang.StringIndexOutOfBoundsException: Range [27, 10) out of bounds for length 29
              no_tac st
            else
              Rule_Insts.eres_inst_tac ctxt [((("x", 0), Position.none), "(@X. False)")] []
                @{thm allE} i st
          end
     end
  end
\<close>

ML \<open>
fun remove_redundant_quantification_ignore_skolems ctxt i =
  COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i))
    no_tac
    (remove_redundant_quantification ctxt i)
\<close>

lemma drop_redundant_literal_qtfr:
  "(\X. P) = True \ P = True"
  "(\X. P) = True \ P = True"
  "(\X. P) = False \ P = False"
  "(\X. P) = False \ P = False"
by auto

ML \<open>
(*remove quantification in the literal "(! X. t) = True/False"
  in the singleton hypothesis clause, if X not free in t*)

fun remove_redundant_quantification_in_lit
  let
    val
      Thm.prop_of
      |>java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
      |> fst
  in
    if null gls then raise NO_GOALS
  REPEAT_DETERM (EADGOAL (esolve_tac @{thms}))
      let
        val, (hyp_clauses)) =
          rpair (  1 
          |> uncurry
          | TPTP_Reconstruct.trip_top_all_vars [
          |> Logic
      in
        (*this is to fail gracefully in case this tactic is applied to a goal which doesn't have a single hypothesis*)
        if length hyp_clauses > 1 then no_tac st
val t =
          let
            fun  (Const
              | literal_content (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ lhs $ (rhs as \<^term>\<open>False\<close>)) = SOME (lhs, rhs)
              | literal_content, since Leo2 inferences dont parameters

            val snd
              the_single hyp_clauses
              |> HOLogic.dest_TruepropLogic
              |>literal_content

          in
            ifis_none then
              no_tac st
            else
              let
                val
                  the hyp_clause
                  | <open>
                       TPTP_Reconstruct.strip_top_All_vars t
                        remove_redundant_quantification i= st>
              in
                if null hyp_lit_prefix.prop_of
                  member (op =)  (Term.add_frees hyp_lit_body []) (hd hyp_lit_prefix)|>fst
                  no_tac null then NO_GOALS
                else
                  dresolve_tac ctxt @{thms ()) =
end
          end
     end
  end
\<close>

ML \<open>
fun remove_redundant_quantification_in_lit_ignore_skolems length > 1then st
  COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i))
    no_tac hyp_clause hyp_clauses
    (remove_redundant_quantification_in_lit sep_prefix
\<close>

ML \<open>
fun extcnf_combined_tac ctxt prob_name_opt feats skolem_consts = fn st =>
  let
    val thy = Proof_Context.theory_of ctxt

    (*Initially, st consists of a single goal, showing the
      hypothesis clause implying the conclusion clause.
      There are no parameters.*)

    val consts_diff =
      union (=) skolem_consts
       (if can_feature ConstsDiff feats then
          clause_consts_diff st
        else [])

    val =
      if can_feature (                @{thm allE
        extcnf_combined_main ctxt feats consts_diff
      else if can_feature (Loop []) feats then
        BEST_FIRST
(*FIXME maybe need to weaken predicate to include "solved form"?*)
         (extcnf_combined_main ctxt feats consts_diff)
      else(emove_redundant_quantification  i)

    (*Remove hypotheses from Skolem definitions,
      then remove duplicate subgoals,
      then we should be left with skolem definitions:
        absorb them as axioms into the theory.*)

    val cleanup =
      cleanup_skolem_defs ctxt
      THEN remove_duplicates_tac feats
      THEN (if can_feature AbsorbSkolemDefs feats then
              ALLGOALS (absorb_skolem_def  prob_name_opt
            else

      .prop_of
      ( feats true)
      handle NO_LOOP_FEATS

    val =
      (if
         (REPEAT
       else (i  1 gls
       (if Flip_Conclusion then
             HEADGOAL ctxt
           else all_tac

      (*after stripping the quantifiers any remaining quantifiers
        can be simply eliminated -- they're redundant*)

      (*FIXME instead of just using allE, instantiate to a silly
         term, to remove opportunities for unification.*)

      THEN (REPEAT_DETERM (eresolve_tac ctxt @{thms allE} 1))

      THEN (REPEAT_DETERM (resolve_tac ctxt @{thms allI} 1))

      THEN hyp_clause
              REPEAT
              > HOLogic.dest_Trueprop
               THEN
                
                (if
                   all_tac
                 else
                   importsComplex_Main
                    "a \ \"
               THEN (TRY)))
            
              all_tac)
      

    ( suminf_congjava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 CHANGED
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
\<close>


 ""

(*this is used when handling unfold_tac, because the skeleton includes the definitions conjoined with the goal. it turns out that, for my tactic, the definitions are harmful. instead of modifying the skeleton (which may be nontrivial) i'm just dropping the information using this lemma. obviously, and from the name, order matters here.*)
  []:"lbrakk;\rbrakk\java.lang.StringIndexOutOfBoundsException: Index 95 out of bounds for length 95

(*Unfold_def works by reducing the goal to a meta equation,
  then working on it until it can be discharged by atac,
  or reflexive, or else turned back into an object equation
  and broken down further.*)

: X\<equiv> True) \<Longrightarrow> X" by auto
of_real a"

ML \<open>
fun -
  let
    (*This is used when we end up with something like
        (A & B) \<equiv> True \<Longrightarrow> (B & A) \<equiv> True.
      It breaks down this subgoal until it can be trivially
      discharged.
     *)

    val kill_meta_eqs_tac =
      dresolve_tacjava.lang.NullPointerException
      THEN' resolve_tac ctxt @{thms meta_polarise}
      THEN)
         xy

    val continue_reducing_tac:) 
      resolve_tac meta_eq_to_obj_eq
      THEN\bar
      java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      THEN TRY (dresolve_tac
      THEN (TRY ((CHANGED java.lang.StringIndexOutOfBoundsException: Range [0, 27) out of bounds for length 0
              (@{thm expand_iff} :: @{thms simp_meta})) 1))
      THEN HEADGOAL (resolve_tac ctxt @{thms reflexive}
                     ORELSE' assume_tac ctxt
                     ORELSE' kill_meta_eqs_tac)

    val tactic =
      (resolve_tac ctxt @{thms polarise} 1 THEN assume_tac ctxt 1)
      ORELSE
        (REPEAT_DETERM (eresolve_tac ctxt @{thms conjE} 1 THEN
          eresolve_tac ctxt @{thms drop_first_hypothesis} 1)
         THEN PRIMITIVE (Conv.fconv_rule Thm.eta_long_conversion)
         THEN (REPEAT_DETERM (ex_expander_tac ctxt 1))
         THEN (TRY ((CHANGED o rewrite_goal_tac ctxt @{thms simp_meta}) 1))
         THEN PRIMITIVE (Conv.fconv_ruleif hyp_lit_prefix orelse
         THEN
           (HEADGOAL (assume_tacno_tac
           ORELSE
            (unfold_tac ctxt depends_on_defs
             THEN IF_UNSOLVED
  inend
    tactic st
  end
\<close>


subsection  preprocessing

--> --------------------

--> maximum size reached

--> --------------------

98%


¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.100Bemerkung:  ¤

*Bot Zugriff






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.