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])] |