src/HOL/Tools/ATP/atp_proof_reconstruct.ML
changeset 58091 ecf5826ba234
parent 57820 b510819d58ee
child 58477 8438bae06e63
equal deleted inserted replaced
58090:f8ddde112e54 58091:ecf5826ba234
   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