src/HOL/Tools/ATP/atp_waldmeister.ML
changeset 69593 3dda49e08b9d
parent 59970 e9f73d87d904
equal deleted inserted replaced
69592:a80d8ec6c998 69593:3dda49e08b9d
    45 structure ATP_Waldmeister_Skolemizer : ATP_WALDMEISTER_SKOLEMIZER =
    45 structure ATP_Waldmeister_Skolemizer : ATP_WALDMEISTER_SKOLEMIZER =
    46 struct
    46 struct
    47 
    47 
    48 open HOLogic
    48 open HOLogic
    49 
    49 
    50 fun contains_quantor (Const (@{const_name Ex}, _) $ _) = true
    50 fun contains_quantor (Const (\<^const_name>\<open>Ex\<close>, _) $ _) = true
    51   | contains_quantor (Const (@{const_name All}, _) $ _) = true
    51   | contains_quantor (Const (\<^const_name>\<open>All\<close>, _) $ _) = true
    52   | contains_quantor (t1 $ t2) = contains_quantor t1 orelse contains_quantor t2
    52   | contains_quantor (t1 $ t2) = contains_quantor t1 orelse contains_quantor t2
    53   | contains_quantor _ = false
    53   | contains_quantor _ = false
    54 
    54 
    55 fun mk_fun_for_bvar ctxt1 ctxt2 arg_trms (bound_name, ty) =
    55 fun mk_fun_for_bvar ctxt1 ctxt2 arg_trms (bound_name, ty) =
    56   let
    56   let
    91       val (trm', ctxt2', var) = skolem_var ctxt2 x
    91       val (trm', ctxt2', var) = skolem_var ctxt2 x
    92     in
    92     in
    93       (ctxt1, ctxt2', spets, trm', var :: vars)
    93       (ctxt1, ctxt2', spets, trm', var :: vars)
    94     end
    94     end
    95 
    95 
    96 fun skolemize' pos ctxt1 ctxt2 spets vars (Const (@{const_name Not}, _) $ trm') =
    96 fun skolemize' pos ctxt1 ctxt2 spets vars (Const (\<^const_name>\<open>Not\<close>, _) $ trm') =
    97     let
    97     let
    98       val (ctxt1', ctxt2', spets', trm'') = skolemize' (not pos) ctxt1 ctxt2 spets vars trm'
    98       val (ctxt1', ctxt2', spets', trm'') = skolemize' (not pos) ctxt1 ctxt2 spets vars trm'
    99     in
    99     in
   100       (ctxt1', ctxt2', map mk_not spets', mk_not trm'')
   100       (ctxt1', ctxt2', map mk_not spets', mk_not trm'')
   101     end
   101     end
   102   | skolemize' pos ctxt1 ctxt2 spets vars (trm as (Const (@{const_name HOL.eq}, t) $ a $ b)) =
   102   | skolemize' pos ctxt1 ctxt2 spets vars (trm as (Const (\<^const_name>\<open>HOL.eq\<close>, t) $ a $ b)) =
   103     if t = @{typ "bool \<Rightarrow> bool \<Rightarrow> bool"} andalso contains_quantor trm then
   103     if t = \<^typ>\<open>bool \<Rightarrow> bool \<Rightarrow> bool\<close> andalso contains_quantor trm then
   104       skolemize' pos ctxt1 ctxt2 (trm :: spets) vars (mk_conj (mk_imp (a, b), mk_imp (b, a)))
   104       skolemize' pos ctxt1 ctxt2 (trm :: spets) vars (mk_conj (mk_imp (a, b), mk_imp (b, a)))
   105     else
   105     else
   106       (ctxt1, ctxt2, spets, trm)
   106       (ctxt1, ctxt2, spets, trm)
   107   | skolemize' pos ctxt1 ctxt2 spets vars (trm as (Const (name, _) $ Abs x)) =
   107   | skolemize' pos ctxt1 ctxt2 spets vars (trm as (Const (name, _) $ Abs x)) =
   108     if name = @{const_name Ex} orelse name = @{const_name All} then
   108     if name = \<^const_name>\<open>Ex\<close> orelse name = \<^const_name>\<open>All\<close> then
   109       let
   109       let
   110         val is_free =  (name = @{const_name Ex} andalso pos)
   110         val is_free =  (name = \<^const_name>\<open>Ex\<close> andalso pos)
   111           orelse (name = @{const_name All} andalso not pos)
   111           orelse (name = \<^const_name>\<open>All\<close> andalso not pos)
   112         val (ctxt1', ctxt2', spets', trm', vars') =
   112         val (ctxt1', ctxt2', spets', trm', vars') =
   113           skolem_bound is_free ctxt1 ctxt2 (if is_free then trm :: spets else spets) vars x
   113           skolem_bound is_free ctxt1 ctxt2 (if is_free then trm :: spets else spets) vars x
   114       in
   114       in
   115         skolemize' pos ctxt1' ctxt2' spets' vars' trm'
   115         skolemize' pos ctxt1' ctxt2' spets' vars' trm'
   116       end
   116       end
   117     else
   117     else
   118       (ctxt1, ctxt2, spets, trm)
   118       (ctxt1, ctxt2, spets, trm)
   119   | skolemize' pos ctxt1 ctxt2 spets vars ((c as Const (name, _)) $ a $ b) =
   119   | skolemize' pos ctxt1 ctxt2 spets vars ((c as Const (name, _)) $ a $ b) =
   120     if name = @{const_name conj} orelse name = @{const_name disj} orelse
   120     if name = \<^const_name>\<open>conj\<close> orelse name = \<^const_name>\<open>disj\<close> orelse
   121        name = @{const_name implies} then
   121        name = \<^const_name>\<open>implies\<close> then
   122       let
   122       let
   123         val pos_a = if name = @{const_name implies} then not pos else pos
   123         val pos_a = if name = \<^const_name>\<open>implies\<close> then not pos else pos
   124         val (ctxt1', ctxt2', spets', a') = skolemize'  pos_a ctxt1 ctxt2 [] vars a
   124         val (ctxt1', ctxt2', spets', a') = skolemize'  pos_a ctxt1 ctxt2 [] vars a
   125         val (ctxt1'', ctxt2'', spets'', b') = skolemize' pos ctxt1' ctxt2' [] vars b
   125         val (ctxt1'', ctxt2'', spets'', b') = skolemize' pos ctxt1' ctxt2' [] vars b
   126       in
   126       in
   127         (ctxt1'', ctxt2'',
   127         (ctxt1'', ctxt2'',
   128          map (fn trm => c $ a' $ trm) spets'' @ map (fn trm => c $ trm $ b) spets' @ spets,
   128          map (fn trm => c $ a' $ trm) spets'' @ map (fn trm => c $ trm $ b) spets' @ spets,
   246   Some utilitary functions for translation.
   246   Some utilitary functions for translation.
   247 *)
   247 *)
   248 
   248 
   249 fun gen_ascii_tuple str = (str, ascii_of str)
   249 fun gen_ascii_tuple str = (str, ascii_of str)
   250 
   250 
   251 fun mk_eq_true (trm as (Const (@{const_name HOL.eq}, _) $ _ $ _)) = (NONE,trm)
   251 fun mk_eq_true (trm as (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ _ $ _)) = (NONE,trm)
   252   | mk_eq_true trm = (SOME trm,HOLogic.mk_eq (trm, @{term True}))
   252   | mk_eq_true trm = (SOME trm,HOLogic.mk_eq (trm, \<^term>\<open>True\<close>))
   253 
   253 
   254 val is_lambda_name = String.isPrefix lam_lifted_poly_prefix
   254 val is_lambda_name = String.isPrefix lam_lifted_poly_prefix
   255 
   255 
   256 fun lookup table k =
   256 fun lookup table k =
   257   List.find (fn (key, _) => key = k) table
   257   List.find (fn (key, _) => key = k) table
   356   | trm_to_atp'' thy (trm1 $ trm2) args = trm_to_atp'' thy trm1 (trm_to_atp'' thy trm2 [] @ args)
   356   | trm_to_atp'' thy (trm1 $ trm2) args = trm_to_atp'' thy trm1 (trm_to_atp'' thy trm2 [] @ args)
   357   | trm_to_atp'' _ _ _ = raise FailureMessage (WM_ERROR_MSG ^ "Unexpected term")
   357   | trm_to_atp'' _ _ _ = raise FailureMessage (WM_ERROR_MSG ^ "Unexpected term")
   358 
   358 
   359 fun trm_to_atp' thy trm = trm_to_atp'' thy trm [] |> hd
   359 fun trm_to_atp' thy trm = trm_to_atp'' thy trm [] |> hd
   360 
   360 
   361 fun eq_trm_to_atp thy (Const (@{const_name HOL.eq}, _) $ lhs $ rhs) =
   361 fun eq_trm_to_atp thy (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ lhs $ rhs) =
   362     ATerm ((("equal", "equal"), []), [trm_to_atp' thy lhs, trm_to_atp' thy rhs])
   362     ATerm ((("equal", "equal"), []), [trm_to_atp' thy lhs, trm_to_atp' thy rhs])
   363   | eq_trm_to_atp _ _ = raise FailureMessage (WM_ERROR_MSG ^ "Non-eq term")
   363   | eq_trm_to_atp _ _ = raise FailureMessage (WM_ERROR_MSG ^ "Non-eq term")
   364 
   364 
   365 (* Translation from ATP terms to Isabelle terms. *)
   365 (* Translation from ATP terms to Isabelle terms. *)
   366 
   366 
   397         [_, _] => eq_const dummyT
   397         [_, _] => eq_const dummyT
   398       | _ => raise FailureMessage
   398       | _ => raise FailureMessage
   399         (WM_ERROR_MSG ^ "waldmeister equals needs 2 arguments but has " ^
   399         (WM_ERROR_MSG ^ "waldmeister equals needs 2 arguments but has " ^
   400          Int.toString (length args)))
   400          Int.toString (length args)))
   401     else if name = waldmeister_true then
   401     else if name = waldmeister_true then
   402       @{term True}
   402       \<^term>\<open>True\<close>
   403     else if name = waldmeister_false then
   403     else if name = waldmeister_false then
   404       @{term False}
   404       \<^term>\<open>False\<close>
   405     else
   405     else
   406       raise FailureMessage
   406       raise FailureMessage
   407         (WM_ERROR_MSG ^ "Unknown name prefix when parsing Waldmeister proof: name = " ^ name)
   407         (WM_ERROR_MSG ^ "Unknown name prefix when parsing Waldmeister proof: name = " ^ name)
   408   end
   408   end
   409 
   409 
   413      | _ => Term.list_comb (construct_term thy (name, args), map (atp_to_trm' thy) args))
   413      | _ => Term.list_comb (construct_term thy (name, args), map (atp_to_trm' thy) args))
   414      | atp_to_trm' _ _ = raise FailureMessage (WM_ERROR_MSG ^ "atp_to_trm' expects ATerm")
   414      | atp_to_trm' _ _ = raise FailureMessage (WM_ERROR_MSG ^ "atp_to_trm' expects ATerm")
   415 
   415 
   416 fun atp_to_trm thy (ATerm (("equal", _), [lhs, rhs])) =
   416 fun atp_to_trm thy (ATerm (("equal", _), [lhs, rhs])) =
   417     mk_eq (atp_to_trm' thy lhs, atp_to_trm' thy rhs)
   417     mk_eq (atp_to_trm' thy lhs, atp_to_trm' thy rhs)
   418   | atp_to_trm _ (ATerm (("$true", _), _)) = @{term True}
   418   | atp_to_trm _ (ATerm (("$true", _), _)) = \<^term>\<open>True\<close>
   419   | atp_to_trm _ _ = raise FailureMessage (WM_ERROR_MSG ^ "atp_to_trm expects ATerm")
   419   | atp_to_trm _ _ = raise FailureMessage (WM_ERROR_MSG ^ "atp_to_trm expects ATerm")
   420 
   420 
   421 fun formula_to_trm thy (AAtom aterm) = aterm |> atp_to_trm thy
   421 fun formula_to_trm thy (AAtom aterm) = aterm |> atp_to_trm thy
   422   | formula_to_trm thy (AConn (ANot, [aterm])) =
   422   | formula_to_trm thy (AConn (ANot, [aterm])) =
   423     mk_not (formula_to_trm thy aterm)
   423     mk_not (formula_to_trm thy aterm)
   560     NONE => [proof_step] |
   560     NONE => [proof_step] |
   561     SOME (_, ([], _)) => [proof_step] |
   561     SOME (_, ([], _)) => [proof_step] |
   562     SOME (_, (step :: steps,_)) =>
   562     SOME (_, (step :: steps,_)) =>
   563       let
   563       let
   564         val raw_trm = dest_Trueprop trm
   564         val raw_trm = dest_Trueprop trm
   565         val is_narrowing = raw_trm = @{term "True = False"} orelse raw_trm = @{term "False = True"}
   565         val is_narrowing = raw_trm = \<^term>\<open>True = False\<close> orelse raw_trm = \<^term>\<open>False = True\<close>
   566         val is_conjecture = String.isPrefix "1.0.0.0" waldmeister_name andalso not is_narrowing
   566         val is_conjecture = String.isPrefix "1.0.0.0" waldmeister_name andalso not is_narrowing
   567       in
   567       in
   568         if is_narrowing then
   568         if is_narrowing then
   569           [proof_step]
   569           [proof_step]
   570         else
   570         else