622 |
622 |
623 fun take_distinct_vars seen ((t as Var _) :: ts) = |
623 fun take_distinct_vars seen ((t as Var _) :: ts) = |
624 if member (op aconv) seen t then rev seen else take_distinct_vars (t :: seen) ts |
624 if member (op aconv) seen t then rev seen else take_distinct_vars (t :: seen) ts |
625 | take_distinct_vars seen _ = rev seen |
625 | take_distinct_vars seen _ = rev seen |
626 |
626 |
627 fun unskolemize_term skos t = |
627 fun unskolemize_term skos = |
628 let |
628 let |
629 val is_skolem = member (op =) skos |
629 val is_skolem = member (op =) skos |
630 |
630 |
631 fun find_args args (t $ u) = find_args (u :: args) t #> find_args [] u |
631 fun find_argless_skolem (Free _ $ Var _) = NONE |
632 | find_args _ (Abs (_, _, t)) = find_args [] t |
632 | find_argless_skolem (Free (x as (s, _))) = if is_skolem s then SOME x else NONE |
633 | find_args args (Free (s, _)) = |
633 | find_argless_skolem (t $ u) = |
634 if is_skolem s then |
634 (case find_argless_skolem t of NONE => find_argless_skolem u | sk => sk) |
635 let val new = take_distinct_vars [] args in |
635 | find_argless_skolem (Abs (_, _, t)) = find_argless_skolem t |
636 (fn [] => new | old => if length new < length old then new else old) |
636 | find_argless_skolem _ = NONE |
|
637 |
|
638 fun find_skolem_arg (Free (s, _) $ Var v) = if is_skolem s then SOME v else NONE |
|
639 | find_skolem_arg (t $ u) = (case find_skolem_arg t of NONE => find_skolem_arg u | v => v) |
|
640 | find_skolem_arg (Abs (_, _, t)) = find_skolem_arg t |
|
641 | find_skolem_arg _ = NONE |
|
642 |
|
643 fun find_var (Var v) = SOME v |
|
644 | find_var (t $ u) = (case find_var t of NONE => find_var u | v => v) |
|
645 | find_var (Abs (_, _, t)) = find_var t |
|
646 | find_var _ = NONE |
|
647 |
|
648 fun find_next_var t = |
|
649 (case find_skolem_arg t of |
|
650 NONE => find_var t |
|
651 | v => v) |
|
652 |
|
653 fun kill_skolem_arg (t as Free (s, T) $ Var _) = |
|
654 if is_skolem s then Free (s, range_type T) else t |
|
655 | kill_skolem_arg (t $ u) = kill_skolem_arg t $ kill_skolem_arg u |
|
656 | kill_skolem_arg (Abs (s, T, t)) = Abs (s, T, kill_skolem_arg t) |
|
657 | kill_skolem_arg t = t |
|
658 |
|
659 val safe_abstract_over = abstract_over o apsnd (incr_boundvars 1) |
|
660 |
|
661 fun unskolem t = |
|
662 (case find_argless_skolem t of |
|
663 SOME (x as (s, T)) => |
|
664 HOLogic.exists_const T $ Abs (s, T, unskolem (safe_abstract_over (Free x, t))) |
|
665 | NONE => |
|
666 (case find_next_var t of |
|
667 SOME (v as ((s, _), T)) => |
|
668 let |
|
669 val (haves, have_nots) = |
|
670 HOLogic.disjuncts t |
|
671 |> List.partition (Term.exists_subterm (curry (op =) (Var v))) |
|
672 |> pairself (fn lits => fold (curry s_disj) lits @{term False}) |
|
673 in |
|
674 s_disj (HOLogic.all_const T |
|
675 $ Abs (s, T, unskolem (safe_abstract_over (Var v, kill_skolem_arg haves))), |
|
676 unskolem have_nots) |
637 end |
677 end |
638 else |
678 | NONE => t)) |
639 I |
|
640 | find_args _ _ = I |
|
641 |
|
642 val alls = find_args [] t [] |
|
643 val num_alls = length alls |
|
644 |
|
645 fun fix_skos args (t $ u) = fix_skos (fix_skos [] u :: args) t |
|
646 | fix_skos args (t as Free (s, T)) = |
|
647 if is_skolem s then list_comb (Free (s, funpow num_alls body_type T), drop num_alls args) |
|
648 else list_comb (t, args) |
|
649 | fix_skos [] (Abs (s, T, t)) = Abs (s, T, fix_skos [] t) |
|
650 | fix_skos [] t = t |
|
651 | fix_skos args t = list_comb (fix_skos [] t, args) |
|
652 |
|
653 val t' = fix_skos [] t |
|
654 |
|
655 fun add_skolem (t as Free (s, _)) = is_skolem s ? insert (op aconv) t |
|
656 | add_skolem _ = I |
|
657 |
|
658 val exs = Term.fold_aterms add_skolem t' [] |
|
659 in |
679 in |
660 t' |
680 HOLogic.mk_Trueprop o unskolem o HOLogic.dest_Trueprop |
661 |> HOLogic.dest_Trueprop |
|
662 |> fold exists_of exs |> Term.map_abs_vars (K Name.uu) |
|
663 |> fold_rev forall_of alls |
|
664 |> HOLogic.mk_Trueprop |
|
665 end |
681 end |
666 |
682 |
667 fun rename_skolem_args t = |
683 fun rename_skolem_args t = |
668 let |
684 let |
669 fun add_skolem_args (Abs (_, _, t)) = add_skolem_args t |
685 fun add_skolem_args (Abs (_, _, t)) = add_skolem_args t |