src/HOL/Tools/ATP/atp_proof_reconstruct.ML
changeset 57787 498b5b00f37f
parent 57785 0388026060d1
child 57788 0a38c47ebb69
equal deleted inserted replaced
57786:1f0efb4974fc 57787:498b5b00f37f
    51   val termify_atp_proof : Proof.context -> string -> ATP_Problem.atp_format ->
    51   val termify_atp_proof : Proof.context -> string -> ATP_Problem.atp_format ->
    52     ATP_Problem_Generate.type_enc -> string Symtab.table -> (string * term) list ->
    52     ATP_Problem_Generate.type_enc -> string Symtab.table -> (string * term) list ->
    53     int Symtab.table -> string atp_proof -> (term, string) atp_step list
    53     int Symtab.table -> string atp_proof -> (term, string) atp_step list
    54   val repair_waldmeister_endgame : (term, 'a) atp_step list -> (term, 'a) atp_step list
    54   val repair_waldmeister_endgame : (term, 'a) atp_step list -> (term, 'a) atp_step list
    55   val infer_formulas_types : Proof.context -> term list -> term list
    55   val infer_formulas_types : Proof.context -> term list -> term list
    56   val introduce_spass_skolem : (term, string) atp_step list -> (term, string) atp_step list
    56   val introduce_spass_skolems : (term, string) atp_step list -> (term, string) atp_step list
    57   val factify_atp_proof : (string * 'a) list -> term list -> term -> (term, string) atp_step list ->
    57   val factify_atp_proof : (string * 'a) list -> term list -> term -> (term, string) atp_step list ->
    58     (term, string) atp_step list
    58     (term, string) atp_step list
    59 end;
    59 end;
    60 
    60 
    61 structure ATP_Proof_Reconstruct : ATP_PROOF_RECONSTRUCT =
    61 structure ATP_Proof_Reconstruct : ATP_PROOF_RECONSTRUCT =
   230   else
   230   else
   231     (s, Sign.the_const_type thy s) |> Sign.const_typargs thy |> length
   231     (s, Sign.the_const_type thy s) |> Sign.const_typargs thy |> length
   232 
   232 
   233 fun slack_fastype_of t = fastype_of t handle TERM _ => Type_Infer.anyT @{sort type}
   233 fun slack_fastype_of t = fastype_of t handle TERM _ => Type_Infer.anyT @{sort type}
   234 
   234 
   235 (* Cope with "tt(X) = X" atoms, where "X" is existentially quantified. *)
       
   236 fun loose_aconv (Free (s, _), Free (s', _)) = s = s'
       
   237   | loose_aconv (t, t') = t aconv t'
       
   238 
       
   239 val spass_skolem_prefix = "sk" (* "skc" or "skf" *)
   235 val spass_skolem_prefix = "sk" (* "skc" or "skf" *)
   240 val vampire_skolem_prefix = "sK"
   236 val vampire_skolem_prefix = "sK"
   241 
   237 
   242 fun var_index_of_textual textual = if textual then 0 else 1
   238 fun var_index_of_textual textual = if textual then 0 else 1
   243 
   239 
   248     val normTs = vars |> AList.group (op =) |> map (apsnd hd)
   244     val normTs = vars |> AList.group (op =) |> map (apsnd hd)
   249     fun norm_var_types (Var (x, T)) =
   245     fun norm_var_types (Var (x, T)) =
   250         Var (x, the_default T (AList.lookup (op =) normTs x))
   246         Var (x, the_default T (AList.lookup (op =) normTs x))
   251       | norm_var_types t = t
   247       | norm_var_types t = t
   252   in t |> map_aterms norm_var_types |> fold_rev quant_of (map Var normTs) end
   248   in t |> map_aterms norm_var_types |> fold_rev quant_of (map Var normTs) end
   253 
       
   254 
   249 
   255 (* Higher-order translation. Variables are typed (although we don't use that information). Lambdas
   250 (* Higher-order translation. Variables are typed (although we don't use that information). Lambdas
   256    are typed. The code is similar to "term_of_atp_fo". *)
   251    are typed. The code is similar to "term_of_atp_fo". *)
   257 fun term_of_atp_ho ctxt sym_tab =
   252 fun term_of_atp_ho ctxt sym_tab =
   258   let
   253   let
   683     |> fold exists_of exs |> Term.map_abs_vars (K Name.uu)
   678     |> fold exists_of exs |> Term.map_abs_vars (K Name.uu)
   684     |> fold_rev forall_of alls
   679     |> fold_rev forall_of alls
   685     |> HOLogic.mk_Trueprop
   680     |> HOLogic.mk_Trueprop
   686   end
   681   end
   687 
   682 
   688 fun introduce_spass_skolem [] = []
   683 fun introduce_spass_skolems proof =
   689   | introduce_spass_skolem (proof as (_, _, _, rule1, _) :: _) =
   684   let
   690     if rule1 = spass_input_rule then
   685     fun add_sko (Free (s, _)) = String.isPrefix spass_skolem_prefix s ? insert (op =) s
       
   686       | add_sko _ = I
       
   687 
       
   688     (* union-find would be faster *)
       
   689     fun add_cycle [] = I
       
   690       | add_cycle ss =
       
   691         fold (fn s => Graph.default_node (s, ())) ss
       
   692         #> fold Graph.add_edge (ss ~~ tl ss @ [hd ss])
       
   693 
       
   694     val (input_steps, other_steps) = List.partition (null o #5) proof
       
   695 
       
   696     val skoss = map (fn (_, _, t, _, _) => Term.fold_aterms add_sko t []) input_steps
       
   697     val skoss_input_steps = filter_out (null o fst) (skoss ~~ input_steps)
       
   698     val groups = Graph.strong_conn (fold add_cycle skoss Graph.empty)
       
   699 
       
   700     fun step_name_of_group skos = (implode skos, [])
       
   701     fun in_group group = member (op =) group o hd
       
   702     fun group_of sko = the (find_first (fn group => in_group group sko) groups)
       
   703 
       
   704     fun new_steps (skoss_steps : (string list * (term, 'a) atp_step) list) group =
   691       let
   705       let
   692         fun add_sko (Free (s, _)) = String.isPrefix spass_skolem_prefix s ? insert (op =) s
   706         val name = step_name_of_group group
   693           | add_sko _ = I
   707         val name0 = name |>> prefix "0"
   694 
   708         val t = skoss_steps
   695         (* union-find would be faster *)
   709           |> map (snd #> #3 #> HOLogic.dest_Trueprop)
   696         fun add_cycle [] = I
   710           |> Library.foldr1 s_conj
   697           | add_cycle ss =
   711           |> HOLogic.mk_Trueprop
   698             fold (fn s => Graph.default_node (s, ())) ss
   712         val skos = fold (union (op =) o fst) skoss_steps []
   699             #> fold Graph.add_edge (ss ~~ tl ss @ [hd ss])
   713         val deps = map (snd #> #1) skoss_steps
   700 
       
   701         val (input_steps, other_steps) = List.partition (null o #5) proof
       
   702 
       
   703         val skoss = map (fn (_, _, t, _, _) => Term.fold_aterms add_sko t []) input_steps
       
   704         val skoss_input_steps = filter_out (null o fst) (skoss ~~ input_steps)
       
   705         val groups = Graph.strong_conn (fold add_cycle skoss Graph.empty)
       
   706 
       
   707         fun step_name_of_group skos = (implode skos, [])
       
   708         fun in_group group = member (op =) group o hd
       
   709         fun group_of sko = the (find_first (fn group => in_group group sko) groups)
       
   710 
       
   711         fun new_steps (skoss_steps : (string list * (term, 'a) atp_step) list) group =
       
   712           let
       
   713             val name = step_name_of_group group
       
   714             val name0 = name |>> prefix "0"
       
   715             val t =
       
   716               skoss_steps
       
   717               |> map (snd #> #3 #> HOLogic.dest_Trueprop)
       
   718               |> Library.foldr1 s_conj
       
   719               |> HOLogic.mk_Trueprop
       
   720             val skos = fold (union (op =) o fst) skoss_steps []
       
   721             val deps = map (snd #> #1) skoss_steps
       
   722           in
       
   723             [(name0, Unknown, unskolemize_term skos t, spass_pre_skolemize_rule, deps),
       
   724              (name, Unknown, t, spass_skolemize_rule, [name0])]
       
   725           end
       
   726 
       
   727         val sko_steps =
       
   728           maps (fn group => new_steps (filter (in_group group o fst) skoss_input_steps) group)
       
   729             groups
       
   730 
       
   731         val old_news =
       
   732           map (fn (skos, (name, _, _, _, _)) => (name, [step_name_of_group (group_of skos)]))
       
   733             skoss_input_steps
       
   734         val repair_deps = fold replace_dependencies_in_line old_news
       
   735       in
   714       in
   736         input_steps @ sko_steps @ map repair_deps other_steps
   715         [(name0, Unknown, unskolemize_term skos t, spass_pre_skolemize_rule, deps),
       
   716          (name, Unknown, t, spass_skolemize_rule, [name0])]
   737       end
   717       end
   738   else
   718 
   739     proof
   719     val sko_steps =
       
   720       maps (fn group => new_steps (filter (in_group group o fst) skoss_input_steps) group) groups
       
   721 
       
   722     val old_news =
       
   723       map (fn (skos, (name, _, _, _, _)) => (name, [step_name_of_group (group_of skos)]))
       
   724         skoss_input_steps
       
   725     val repair_deps = fold replace_dependencies_in_line old_news
       
   726   in
       
   727     input_steps @ sko_steps @ map repair_deps other_steps
       
   728   end
   740 
   729 
   741 fun factify_atp_proof facts hyp_ts concl_t atp_proof =
   730 fun factify_atp_proof facts hyp_ts concl_t atp_proof =
   742   let
   731   let
   743     fun factify_step ((num, ss), role, t, rule, deps) =
   732     fun factify_step ((num, ss), role, t, rule, deps) =
   744       let
   733       let