src/HOL/Tools/ATP/atp_proof_reconstruct.ML
changeset 57788 0a38c47ebb69
parent 57787 498b5b00f37f
child 57789 a73255cffb5b
equal deleted inserted replaced
57787:498b5b00f37f 57788:0a38c47ebb69
   254     val thy = Proof_Context.theory_of ctxt
   254     val thy = Proof_Context.theory_of ctxt
   255     val var_index = var_index_of_textual true
   255     val var_index = var_index_of_textual true
   256 
   256 
   257     fun do_term opt_T u =
   257     fun do_term opt_T u =
   258       (case u of
   258       (case u of
   259         AAbs(((var, ty), term), []) =>
   259         AAbs (((var, ty), term), []) =>
   260         let
   260         let
   261           val typ = typ_of_atp_type ctxt ty
   261           val typ = typ_of_atp_type ctxt ty
   262           val var_name = repair_var_name true var
   262           val var_name = repair_var_name true var
   263           val tm = do_term NONE term
   263           val tm = do_term NONE term
   264         in quantify_over_var true lambda' var_name typ tm end
   264         in quantify_over_var true lambda' var_name typ tm end
   640     if member (op aconv) seen t then rev seen else take_distinct_vars (t :: seen) ts
   640     if member (op aconv) seen t then rev seen else take_distinct_vars (t :: seen) ts
   641   | take_distinct_vars seen _ = rev seen
   641   | take_distinct_vars seen _ = rev seen
   642 
   642 
   643 fun unskolemize_term skos t =
   643 fun unskolemize_term skos t =
   644   let
   644   let
   645     val is_sko = member (op =) skos
   645     val is_skolem = member (op =) skos
   646 
   646 
   647     fun find_args args (t $ u) = find_args (u :: args) t #> find_args [] u
   647     fun find_args args (t $ u) = find_args (u :: args) t #> find_args [] u
   648       | find_args _ (Abs (_, _, t)) = find_args [] t
   648       | find_args _ (Abs (_, _, t)) = find_args [] t
   649       | find_args args (Free (s, _)) =
   649       | find_args args (Free (s, _)) =
   650         if is_sko s then
   650         if is_skolem s then
   651           let val new = take_distinct_vars [] args in
   651           let val new = take_distinct_vars [] args in
   652             (fn [] => new | old => if length new < length old then new else old)
   652             (fn [] => new | old => if length new < length old then new else old)
   653           end
   653           end
   654         else
   654         else
   655           I
   655           I
   658     val alls = find_args [] t []
   658     val alls = find_args [] t []
   659     val num_alls = length alls
   659     val num_alls = length alls
   660 
   660 
   661     fun fix_skos args (t $ u) = fix_skos (fix_skos [] u :: args) t
   661     fun fix_skos args (t $ u) = fix_skos (fix_skos [] u :: args) t
   662       | fix_skos args (t as Free (s, T)) =
   662       | fix_skos args (t as Free (s, T)) =
   663         if is_sko s then list_comb (Free (s, funpow num_alls body_type T), drop num_alls args)
   663         if is_skolem s then list_comb (Free (s, funpow num_alls body_type T), drop num_alls args)
   664         else list_comb (t, args)
   664         else list_comb (t, args)
   665       | fix_skos [] (Abs (s, T, t)) = Abs (s, T, fix_skos [] t)
   665       | fix_skos [] (Abs (s, T, t)) = Abs (s, T, fix_skos [] t)
   666       | fix_skos [] t = t
   666       | fix_skos [] t = t
   667       | fix_skos args t = list_comb (fix_skos [] t, args)
   667       | fix_skos args t = list_comb (fix_skos [] t, args)
   668 
   668 
   669     val t' = fix_skos [] t
   669     val t' = fix_skos [] t
   670 
   670 
   671     fun add_sko (t as Free (s, _)) = is_sko s ? insert (op aconv) t
   671     fun add_skolem (t as Free (s, _)) = is_skolem s ? insert (op aconv) t
   672       | add_sko _ = I
   672       | add_skolem _ = I
   673 
   673 
   674     val exs = Term.fold_aterms add_sko t' []
   674     val exs = Term.fold_aterms add_skolem t' []
   675   in
   675   in
   676     t'
   676     t'
   677     |> HOLogic.dest_Trueprop
   677     |> HOLogic.dest_Trueprop
   678     |> fold exists_of exs |> Term.map_abs_vars (K Name.uu)
   678     |> fold exists_of exs |> Term.map_abs_vars (K Name.uu)
   679     |> fold_rev forall_of alls
   679     |> fold_rev forall_of alls
   680     |> HOLogic.mk_Trueprop
   680     |> HOLogic.mk_Trueprop
   681   end
   681   end
   682 
   682 
       
   683 fun rename_skolem_args t =
       
   684   let
       
   685     fun add_skolem_args (Abs (_, _, t)) = add_skolem_args t
       
   686       | add_skolem_args t =
       
   687         (case strip_comb t of
       
   688           (Free (s, _), args as _ :: _) =>
       
   689           if String.isPrefix spass_skolem_prefix s then
       
   690             insert (op =) (s, fst (take_prefix is_Var args))
       
   691           else
       
   692             fold add_skolem_args args
       
   693         | (u, args as _ :: _) => fold add_skolem_args (u :: args)
       
   694         | _ => I)
       
   695 
       
   696     fun subst_of_skolem (sk, args) =
       
   697       map_index (fn (j, Var (z, T)) => (z, Var ((sk ^ "_" ^ string_of_int j, 0), T))) args
       
   698 
       
   699     val subst = maps subst_of_skolem (add_skolem_args t [])
       
   700   in
       
   701     subst_vars ([], subst) t
       
   702   end
       
   703 
   683 fun introduce_spass_skolems proof =
   704 fun introduce_spass_skolems proof =
   684   let
   705   let
   685     fun add_sko (Free (s, _)) = String.isPrefix spass_skolem_prefix s ? insert (op =) s
   706     fun add_skolem (Free (s, _)) = String.isPrefix spass_skolem_prefix s ? insert (op =) s
   686       | add_sko _ = I
   707       | add_skolem _ = I
   687 
   708 
   688     (* union-find would be faster *)
   709     (* union-find would be faster *)
   689     fun add_cycle [] = I
   710     fun add_cycle [] = I
   690       | add_cycle ss =
   711       | add_cycle ss =
   691         fold (fn s => Graph.default_node (s, ())) ss
   712         fold (fn s => Graph.default_node (s, ())) ss
   692         #> fold Graph.add_edge (ss ~~ tl ss @ [hd ss])
   713         #> fold Graph.add_edge (ss ~~ tl ss @ [hd ss])
   693 
   714 
   694     val (input_steps, other_steps) = List.partition (null o #5) proof
   715     val (input_steps, other_steps) = List.partition (null o #5) proof
   695 
   716 
   696     val skoss = map (fn (_, _, t, _, _) => Term.fold_aterms add_sko t []) input_steps
   717     val skoss = map (fn (_, _, t, _, _) => Term.fold_aterms add_skolem t []) input_steps
   697     val skoss_input_steps = filter_out (null o fst) (skoss ~~ input_steps)
   718     val skoss_input_steps = filter_out (null o fst) (skoss ~~ input_steps)
   698     val groups = Graph.strong_conn (fold add_cycle skoss Graph.empty)
   719     val groups = Graph.strong_conn (fold add_cycle skoss Graph.empty)
   699 
   720 
   700     fun step_name_of_group skos = (implode skos, [])
   721     fun step_name_of_group skos = (implode skos, [])
   701     fun in_group group = member (op =) group o hd
   722     fun in_group group = member (op =) group o hd
   703 
   724 
   704     fun new_steps (skoss_steps : (string list * (term, 'a) atp_step) list) group =
   725     fun new_steps (skoss_steps : (string list * (term, 'a) atp_step) list) group =
   705       let
   726       let
   706         val name = step_name_of_group group
   727         val name = step_name_of_group group
   707         val name0 = name |>> prefix "0"
   728         val name0 = name |>> prefix "0"
   708         val t = skoss_steps
   729         val t =
   709           |> map (snd #> #3 #> HOLogic.dest_Trueprop)
   730           (case map (snd #> #3) skoss_steps of
   710           |> Library.foldr1 s_conj
   731             [t] => t
   711           |> HOLogic.mk_Trueprop
   732           | ts => ts
       
   733             |> map (HOLogic.dest_Trueprop #> rename_skolem_args)
       
   734             |> Library.foldr1 s_conj
       
   735             |> HOLogic.mk_Trueprop)
   712         val skos = fold (union (op =) o fst) skoss_steps []
   736         val skos = fold (union (op =) o fst) skoss_steps []
   713         val deps = map (snd #> #1) skoss_steps
   737         val deps = map (snd #> #1) skoss_steps
   714       in
   738       in
   715         [(name0, Unknown, unskolemize_term skos t, spass_pre_skolemize_rule, deps),
   739         [(name0, Unknown, unskolemize_term skos t, spass_pre_skolemize_rule, deps),
   716          (name, Unknown, t, spass_skolemize_rule, [name0])]
   740          (name, Unknown, t, spass_skolemize_rule, [name0])]