src/HOL/Tools/Metis/metis_tactic.ML
changeset 59582 0fbed69ff081
parent 59498 50b60f501b05
child 59586 ddf6deaadfe8
equal deleted inserted replaced
59580:cbc38731d42f 59582:0fbed69ff081
    31 val new_skolem = Attrib.setup_config_bool @{binding metis_new_skolem} (K false)
    31 val new_skolem = Attrib.setup_config_bool @{binding metis_new_skolem} (K false)
    32 val advisory_simp = Attrib.setup_config_bool @{binding metis_advisory_simp} (K true)
    32 val advisory_simp = Attrib.setup_config_bool @{binding metis_advisory_simp} (K true)
    33 
    33 
    34 (* Designed to work also with monomorphic instances of polymorphic theorems. *)
    34 (* Designed to work also with monomorphic instances of polymorphic theorems. *)
    35 fun have_common_thm ths1 ths2 =
    35 fun have_common_thm ths1 ths2 =
    36   exists (member (Term.aconv_untyped o apply2 prop_of) ths1) (map Meson.make_meta_clause ths2)
    36   exists (member (Term.aconv_untyped o apply2 Thm.prop_of) ths1) (map Meson.make_meta_clause ths2)
    37 
    37 
    38 (*Determining which axiom clauses are actually used*)
    38 (*Determining which axiom clauses are actually used*)
    39 fun used_axioms axioms (th, Metis_Proof.Axiom _) = SOME (lookth axioms th)
    39 fun used_axioms axioms (th, Metis_Proof.Axiom _) = SOME (lookth axioms th)
    40   | used_axioms _ _ = NONE
    40   | used_axioms _ _ = NONE
    41 
    41 
    46 fun reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth =
    46 fun reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth =
    47   let val thy = Proof_Context.theory_of ctxt in
    47   let val thy = Proof_Context.theory_of ctxt in
    48     (case hol_clause_of_metis ctxt type_enc sym_tab concealed mth of
    48     (case hol_clause_of_metis ctxt type_enc sym_tab concealed mth of
    49       Const (@{const_name HOL.eq}, _) $ _ $ t =>
    49       Const (@{const_name HOL.eq}, _) $ _ $ t =>
    50       let
    50       let
    51         val ct = cterm_of thy t
    51         val ct = Thm.cterm_of thy t
    52         val cT = ctyp_of_term ct
    52         val cT = Thm.ctyp_of_term ct
    53       in refl |> Drule.instantiate' [SOME cT] [SOME ct] end
    53       in refl |> Drule.instantiate' [SOME cT] [SOME ct] end
    54     | Const (@{const_name disj}, _) $ t1 $ t2 =>
    54     | Const (@{const_name disj}, _) $ t1 $ t2 =>
    55       (if can HOLogic.dest_not t1 then t2 else t1)
    55       (if can HOLogic.dest_not t1 then t2 else t1)
    56       |> HOLogic.mk_Trueprop |> cterm_of thy |> Thm.trivial
    56       |> HOLogic.mk_Trueprop |> Thm.cterm_of thy |> Thm.trivial
    57     | _ => raise Fail "expected reflexive or trivial clause")
    57     | _ => raise Fail "expected reflexive or trivial clause")
    58   end
    58   end
    59   |> Meson.make_meta_clause
    59   |> Meson.make_meta_clause
    60 
    60 
    61 fun lam_lifted_of_metis ctxt type_enc sym_tab concealed mth =
    61 fun lam_lifted_of_metis ctxt type_enc sym_tab concealed mth =
    62   let
    62   let
    63     val thy = Proof_Context.theory_of ctxt
    63     val thy = Proof_Context.theory_of ctxt
    64     val tac = rewrite_goals_tac ctxt @{thms lambda_def [abs_def]} THEN resolve_tac ctxt [refl] 1
    64     val tac = rewrite_goals_tac ctxt @{thms lambda_def [abs_def]} THEN resolve_tac ctxt [refl] 1
    65     val t = hol_clause_of_metis ctxt type_enc sym_tab concealed mth
    65     val t = hol_clause_of_metis ctxt type_enc sym_tab concealed mth
    66     val ct = cterm_of thy (HOLogic.mk_Trueprop t)
    66     val ct = Thm.cterm_of thy (HOLogic.mk_Trueprop t)
    67   in Goal.prove_internal ctxt [] ct (K tac) |> Meson.make_meta_clause end
    67   in Goal.prove_internal ctxt [] ct (K tac) |> Meson.make_meta_clause end
    68 
    68 
    69 fun add_vars_and_frees (t $ u) = fold (add_vars_and_frees) [t, u]
    69 fun add_vars_and_frees (t $ u) = fold (add_vars_and_frees) [t, u]
    70   | add_vars_and_frees (Abs (_, _, t)) = add_vars_and_frees t
    70   | add_vars_and_frees (Abs (_, _, t)) = add_vars_and_frees t
    71   | add_vars_and_frees (t as Var _) = insert (op =) t
    71   | add_vars_and_frees (t as Var _) = insert (op =) t
    72   | add_vars_and_frees (t as Free _) = insert (op =) t
    72   | add_vars_and_frees (t as Free _) = insert (op =) t
    73   | add_vars_and_frees _ = I
    73   | add_vars_and_frees _ = I
    74 
    74 
    75 fun introduce_lam_wrappers ctxt th =
    75 fun introduce_lam_wrappers ctxt th =
    76   if Meson_Clausify.is_quasi_lambda_free (prop_of th) then
    76   if Meson_Clausify.is_quasi_lambda_free (Thm.prop_of th) then
    77     th
    77     th
    78   else
    78   else
    79     let
    79     let
    80       val thy = Proof_Context.theory_of ctxt
    80       val thy = Proof_Context.theory_of ctxt
    81       fun conv first ctxt ct =
    81       fun conv first ctxt ct =
    82         if Meson_Clausify.is_quasi_lambda_free (term_of ct) then
    82         if Meson_Clausify.is_quasi_lambda_free (Thm.term_of ct) then
    83           Thm.reflexive ct
    83           Thm.reflexive ct
    84         else
    84         else
    85           (case term_of ct of
    85           (case Thm.term_of ct of
    86             Abs (_, _, u) =>
    86             Abs (_, _, u) =>
    87             if first then
    87             if first then
    88               (case add_vars_and_frees u [] of
    88               (case add_vars_and_frees u [] of
    89                 [] =>
    89                 [] =>
    90                 Conv.abs_conv (conv false o snd) ctxt ct
    90                 Conv.abs_conv (conv false o snd) ctxt ct
    91                 |> (fn th => Meson.first_order_resolve th @{thm Metis.eq_lambdaI})
    91                 |> (fn th => Meson.first_order_resolve th @{thm Metis.eq_lambdaI})
    92               | v :: _ =>
    92               | v :: _ =>
    93                 Abs (Name.uu, fastype_of v, abstract_over (v, term_of ct)) $ v
    93                 Abs (Name.uu, fastype_of v, abstract_over (v, Thm.term_of ct)) $ v
    94                 |> cterm_of thy
    94                 |> Thm.cterm_of thy
    95                 |> Conv.comb_conv (conv true ctxt))
    95                 |> Conv.comb_conv (conv true ctxt))
    96             else
    96             else
    97               Conv.abs_conv (conv false o snd) ctxt ct
    97               Conv.abs_conv (conv false o snd) ctxt ct
    98           | Const (@{const_name Meson.skolem}, _) $ _ => Thm.reflexive ct
    98           | Const (@{const_name Meson.skolem}, _) $ _ => Thm.reflexive ct
    99           | _ => Conv.comb_conv (conv true ctxt) ct)
    99           | _ => Conv.comb_conv (conv true ctxt) ct)
   100       val eq_th = conv true ctxt (cprop_of th)
   100       val eq_th = conv true ctxt (Thm.cprop_of th)
   101       (* We replace the equation's left-hand side with a beta-equivalent term
   101       (* We replace the equation's left-hand side with a beta-equivalent term
   102          so that "Thm.equal_elim" works below. *)
   102          so that "Thm.equal_elim" works below. *)
   103       val t0 $ _ $ t2 = prop_of eq_th
   103       val t0 $ _ $ t2 = Thm.prop_of eq_th
   104       val eq_ct = t0 $ prop_of th $ t2 |> cterm_of thy
   104       val eq_ct = t0 $ Thm.prop_of th $ t2 |> Thm.cterm_of thy
   105       val eq_th' = Goal.prove_internal ctxt [] eq_ct (K (resolve_tac ctxt [eq_th] 1))
   105       val eq_th' = Goal.prove_internal ctxt [] eq_ct (K (resolve_tac ctxt [eq_th] 1))
   106     in Thm.equal_elim eq_th' th end
   106     in Thm.equal_elim eq_th' th end
   107 
   107 
   108 fun clause_params ordering =
   108 fun clause_params ordering =
   109   {ordering = ordering,
   109   {ordering = ordering,
   187     fun fall_back () =
   187     fun fall_back () =
   188       (verbose_warning ctxt
   188       (verbose_warning ctxt
   189            ("Falling back on " ^ quote (metis_call (hd fallback_type_encs) lam_trans) ^ "...");
   189            ("Falling back on " ^ quote (metis_call (hd fallback_type_encs) lam_trans) ^ "...");
   190        FOL_SOLVE unused fallback_type_encs lam_trans ctxt cls ths0)
   190        FOL_SOLVE unused fallback_type_encs lam_trans ctxt cls ths0)
   191   in
   191   in
   192     (case filter (fn t => prop_of t aconv @{prop False}) cls of
   192     (case filter (fn t => Thm.prop_of t aconv @{prop False}) cls of
   193        false_th :: _ => [false_th RS @{thm FalseE}]
   193        false_th :: _ => [false_th RS @{thm FalseE}]
   194      | [] =>
   194      | [] =>
   195      (case Metis_Resolution.loop (Metis_Resolution.new (resolution_params ordering)
   195      (case Metis_Resolution.loop (Metis_Resolution.new (resolution_params ordering)
   196          {axioms = axioms |> map fst, conjecture = []}) of
   196          {axioms = axioms |> map fst, conjecture = []}) of
   197        Metis_Resolution.Contradiction mth =>
   197        Metis_Resolution.Contradiction mth =>
   198        let
   198        let
   199          val _ = trace_msg ctxt (fn () => "METIS RECONSTRUCTION START: " ^ Metis_Thm.toString mth)
   199          val _ = trace_msg ctxt (fn () => "METIS RECONSTRUCTION START: " ^ Metis_Thm.toString mth)
   200          val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt
   200          val ctxt' = fold Variable.declare_constraints (map Thm.prop_of cls) ctxt
   201                       (*add constraints arising from converting goal to clause form*)
   201                       (*add constraints arising from converting goal to clause form*)
   202          val proof = Metis_Proof.proof mth
   202          val proof = Metis_Proof.proof mth
   203          val result = fold (replay_one_inference ctxt' type_enc concealed sym_tab) proof axioms
   203          val result = fold (replay_one_inference ctxt' type_enc concealed sym_tab) proof axioms
   204          val used = map_filter (used_axioms axioms) proof
   204          val used = map_filter (used_axioms axioms) proof
   205          val _ = trace_msg ctxt (K "METIS COMPLETED; clauses actually used:")
   205          val _ = trace_msg ctxt (K "METIS COMPLETED; clauses actually used:")
   241   #> combinators ? map (Meson_Clausify.introduce_combinators_in_theorem ctxt)
   241   #> combinators ? map (Meson_Clausify.introduce_combinators_in_theorem ctxt)
   242   #> Meson.finish_cnf
   242   #> Meson.finish_cnf
   243 
   243 
   244 fun preskolem_tac ctxt st0 =
   244 fun preskolem_tac ctxt st0 =
   245   (if exists (Meson.has_too_many_clauses ctxt)
   245   (if exists (Meson.has_too_many_clauses ctxt)
   246              (Logic.prems_of_goal (prop_of st0) 1) then
   246              (Logic.prems_of_goal (Thm.prop_of st0) 1) then
   247      Simplifier.full_simp_tac (Meson_Clausify.ss_only @{thms not_all not_ex} ctxt) 1
   247      Simplifier.full_simp_tac (Meson_Clausify.ss_only @{thms not_all not_ex} ctxt) 1
   248      THEN CNF.cnfx_rewrite_tac ctxt 1
   248      THEN CNF.cnfx_rewrite_tac ctxt 1
   249    else
   249    else
   250      all_tac) st0
   250      all_tac) st0
   251 
   251 
   267 
   267 
   268 (* Whenever "X" has schematic type variables, we treat "using X by metis" as "by (metis X)" to
   268 (* Whenever "X" has schematic type variables, we treat "using X by metis" as "by (metis X)" to
   269    prevent "Subgoal.FOCUS" from freezing the type variables. We don't do it for nonschematic facts
   269    prevent "Subgoal.FOCUS" from freezing the type variables. We don't do it for nonschematic facts
   270    "X" because this breaks a few proofs (in the rare and subtle case where a proof relied on
   270    "X" because this breaks a few proofs (in the rare and subtle case where a proof relied on
   271    extensionality not being applied) and brings few benefits. *)
   271    extensionality not being applied) and brings few benefits. *)
   272 val has_tvar = exists_type (exists_subtype (fn TVar _ => true | _ => false)) o prop_of
   272 val has_tvar = exists_type (exists_subtype (fn TVar _ => true | _ => false)) o Thm.prop_of
   273 
   273 
   274 fun metis_method ((override_type_encs, lam_trans), ths) ctxt facts =
   274 fun metis_method ((override_type_encs, lam_trans), ths) ctxt facts =
   275   let val (schem_facts, nonschem_facts) = List.partition has_tvar facts in
   275   let val (schem_facts, nonschem_facts) = List.partition has_tvar facts in
   276     HEADGOAL (Method.insert_tac nonschem_facts THEN'
   276     HEADGOAL (Method.insert_tac nonschem_facts THEN'
   277       CHANGED_PROP o metis_tac (these override_type_encs)
   277       CHANGED_PROP o metis_tac (these override_type_encs)