src/HOL/Tools/Function/function_lib.ML
changeset 34232 36a2a3029fd3
parent 33855 cd8acf137c9c
child 35402 115a5a95710a
equal deleted inserted replaced
34231:da4d7d40f2f9 34232:36a2a3029fd3
     1 (*  Title:      HOL/Tools/Function/fundef_lib.ML
     1 (*  Title:      HOL/Tools/Function/fundef_lib.ML
     2     Author:     Alexander Krauss, TU Muenchen
     2     Author:     Alexander Krauss, TU Muenchen
     3 
     3 
     4 A package for general recursive function definitions. 
     4 A package for general recursive function definitions.
     5 Some fairly general functions that should probably go somewhere else... 
     5 Some fairly general functions that should probably go somewhere else...
     6 *)
     6 *)
     7 
     7 
     8 structure Function_Lib =
     8 structure Function_Lib =
     9 struct
     9 struct
    10 
    10 
    11 fun map_option f NONE = NONE 
    11 fun map_option f NONE = NONE
    12   | map_option f (SOME x) = SOME (f x);
    12   | map_option f (SOME x) = SOME (f x);
    13 
    13 
    14 fun fold_option f NONE y = y
    14 fun fold_option f NONE y = y
    15   | fold_option f (SOME x) y = f x y;
    15   | fold_option f (SOME x) y = f x y;
    16 
    16 
    19   | plural sg pl _ = pl
    19   | plural sg pl _ = pl
    20 
    20 
    21 (* lambda-abstracts over an arbitrarily nested tuple
    21 (* lambda-abstracts over an arbitrarily nested tuple
    22   ==> hologic.ML? *)
    22   ==> hologic.ML? *)
    23 fun tupled_lambda vars t =
    23 fun tupled_lambda vars t =
    24     case vars of
    24   case vars of
    25       (Free v) => lambda (Free v) t
    25     (Free v) => lambda (Free v) t
    26     | (Var v) => lambda (Var v) t
    26   | (Var v) => lambda (Var v) t
    27     | (Const ("Pair", Type ("fun", [Ta, Type ("fun", [Tb, _])]))) $ us $ vs =>  
    27   | (Const ("Pair", Type ("fun", [Ta, Type ("fun", [Tb, _])]))) $ us $ vs =>
    28       (HOLogic.split_const (Ta,Tb, fastype_of t)) $ (tupled_lambda us (tupled_lambda vs t))
    28       (HOLogic.split_const (Ta,Tb, fastype_of t)) $ (tupled_lambda us (tupled_lambda vs t))
    29     | _ => raise Match
    29   | _ => raise Match
    30 
    30 
    31 
    31 
    32 fun dest_all (Const ("all", _) $ Abs (a as (_,T,_))) =
    32 fun dest_all (Const ("all", _) $ Abs (a as (_,T,_))) =
    33     let
    33   let
    34       val (n, body) = Term.dest_abs a
    34     val (n, body) = Term.dest_abs a
    35     in
    35   in
    36       (Free (n, T), body)
    36     (Free (n, T), body)
    37     end
    37   end
    38   | dest_all _ = raise Match
    38   | dest_all _ = raise Match
    39 
    39 
    40 
    40 
    41 (* Removes all quantifiers from a term, replacing bound variables by frees. *)
    41 (* Removes all quantifiers from a term, replacing bound variables by frees. *)
    42 fun dest_all_all (t as (Const ("all",_) $ _)) = 
    42 fun dest_all_all (t as (Const ("all",_) $ _)) =
    43     let
    43   let
    44       val (v,b) = dest_all t
    44     val (v,b) = dest_all t
    45       val (vs, b') = dest_all_all b
    45     val (vs, b') = dest_all_all b
    46     in
    46   in
    47       (v :: vs, b')
    47     (v :: vs, b')
    48     end
    48   end
    49   | dest_all_all t = ([],t)
    49   | dest_all_all t = ([],t)
    50 
    50 
    51 
    51 
    52 (* FIXME: similar to Variable.focus *)
    52 (* FIXME: similar to Variable.focus *)
    53 fun dest_all_all_ctx ctx (Const ("all", _) $ Abs (n,T,b)) =
    53 fun dest_all_all_ctx ctx (Const ("all", _) $ Abs (n,T,b)) =
    54     let
    54   let
    55       val [(n', _)] = Variable.variant_frees ctx [] [(n,T)]
    55     val [(n', _)] = Variable.variant_frees ctx [] [(n,T)]
    56       val (_, ctx') = ProofContext.add_fixes [(Binding.name n', SOME T, NoSyn)] ctx
    56     val (_, ctx') = ProofContext.add_fixes [(Binding.name n', SOME T, NoSyn)] ctx
    57 
    57 
    58       val (n'', body) = Term.dest_abs (n', T, b) 
    58     val (n'', body) = Term.dest_abs (n', T, b)
    59       val _ = (n' = n'') orelse error "dest_all_ctx"
    59     val _ = (n' = n'') orelse error "dest_all_ctx"
    60       (* Note: We assume that n' does not occur in the body. Otherwise it would be fixed. *)
    60       (* Note: We assume that n' does not occur in the body. Otherwise it would be fixed. *)
    61 
    61 
    62       val (ctx'', vs, bd) = dest_all_all_ctx ctx' body
    62     val (ctx'', vs, bd) = dest_all_all_ctx ctx' body
    63     in
    63   in
    64       (ctx'', (n', T) :: vs, bd)
    64     (ctx'', (n', T) :: vs, bd)
    65     end
    65   end
    66   | dest_all_all_ctx ctx t = 
    66   | dest_all_all_ctx ctx t =
    67     (ctx, [], t)
    67   (ctx, [], t)
    68 
    68 
    69 
    69 
    70 fun map3 _ [] [] [] = []
    70 fun map3 _ [] [] [] = []
    71   | map3 f (x :: xs) (y :: ys) (z :: zs) = f x y z :: map3 f xs ys zs
    71   | map3 f (x :: xs) (y :: ys) (z :: zs) = f x y z :: map3 f xs ys zs
    72   | map3 _ _ _ _ = raise Library.UnequalLengths;
    72   | map3 _ _ _ _ = raise Library.UnequalLengths;
    84   | map7 _ _ _ _ _ _ _ _ = raise Library.UnequalLengths;
    84   | map7 _ _ _ _ _ _ _ _ = raise Library.UnequalLengths;
    85 
    85 
    86 
    86 
    87 
    87 
    88 (* forms all "unordered pairs": [1, 2, 3] ==> [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)] *)
    88 (* forms all "unordered pairs": [1, 2, 3] ==> [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)] *)
    89 (* ==> library *)
       
    90 fun unordered_pairs [] = []
    89 fun unordered_pairs [] = []
    91   | unordered_pairs (x::xs) = map (pair x) (x::xs) @ unordered_pairs xs
    90   | unordered_pairs (x::xs) = map (pair x) (x::xs) @ unordered_pairs xs
    92 
    91 
    93 
    92 
    94 (* Replaces Frees by name. Works with loose Bounds. *)
    93 (* Replaces Frees by name. Works with loose Bounds. *)
    95 fun replace_frees assoc =
    94 fun replace_frees assoc =
    96     map_aterms (fn c as Free (n, _) => the_default c (AList.lookup (op =) assoc n)
    95   map_aterms (fn c as Free (n, _) => the_default c (AList.lookup (op =) assoc n)
    97                  | t => t)
    96     | t => t)
    98 
    97 
    99 
    98 
   100 fun rename_bound n (Q $ Abs(_, T, b)) = (Q $ Abs(n, T, b))
    99 fun rename_bound n (Q $ Abs (_, T, b)) = (Q $ Abs (n, T, b))
   101   | rename_bound n _ = raise Match
   100   | rename_bound n _ = raise Match
   102 
   101 
   103 fun mk_forall_rename (n, v) =
   102 fun mk_forall_rename (n, v) =
   104     rename_bound n o Logic.all v 
   103   rename_bound n o Logic.all v
   105 
   104 
   106 fun forall_intr_rename (n, cv) thm =
   105 fun forall_intr_rename (n, cv) thm =
   107     let
   106   let
   108       val allthm = forall_intr cv thm
   107     val allthm = forall_intr cv thm
   109       val (_ $ abs) = prop_of allthm
   108     val (_ $ abs) = prop_of allthm
   110     in
   109   in
   111       Thm.rename_boundvars abs (Abs (n, dummyT, Term.dummy_pattern dummyT)) allthm
   110     Thm.rename_boundvars abs (Abs (n, dummyT, Term.dummy_pattern dummyT)) allthm
   112     end
   111   end
   113 
   112 
   114 
   113 
   115 (* Returns the frees in a term in canonical order, excluding the fixes from the context *)
   114 (* Returns the frees in a term in canonical order, excluding the fixes from the context *)
   116 fun frees_in_term ctxt t =
   115 fun frees_in_term ctxt t =
   117     Term.add_frees t []
   116   Term.add_frees t []
   118     |> filter_out (Variable.is_fixed ctxt o fst)
   117   |> filter_out (Variable.is_fixed ctxt o fst)
   119     |> rev
   118   |> rev
   120 
   119 
   121 
   120 
   122 datatype proof_attempt = Solved of thm | Stuck of thm | Fail
   121 datatype proof_attempt = Solved of thm | Stuck of thm | Fail
   123 
   122 
   124 fun try_proof cgoal tac = 
   123 fun try_proof cgoal tac =
   125     case SINGLE tac (Goal.init cgoal) of
   124   case SINGLE tac (Goal.init cgoal) of
   126       NONE => Fail
   125     NONE => Fail
   127     | SOME st =>
   126   | SOME st =>
   128         if Thm.no_prems st
   127     if Thm.no_prems st
   129         then Solved (Goal.finish (Syntax.init_pretty_global (Thm.theory_of_cterm cgoal)) st)
   128     then Solved (Goal.finish (Syntax.init_pretty_global (Thm.theory_of_cterm cgoal)) st)
   130         else Stuck st
   129     else Stuck st
   131 
   130 
   132 
   131 
   133 fun dest_binop_list cn (t as (Const (n, _) $ a $ b)) = 
   132 fun dest_binop_list cn (t as (Const (n, _) $ a $ b)) =
   134     if cn = n then dest_binop_list cn a @ dest_binop_list cn b else [ t ]
   133   if cn = n then dest_binop_list cn a @ dest_binop_list cn b else [ t ]
   135   | dest_binop_list _ t = [ t ]
   134   | dest_binop_list _ t = [ t ]
   136 
   135 
   137 
   136 
   138 (* separate two parts in a +-expression:
   137 (* separate two parts in a +-expression:
   139    "a + b + c + d + e" --> "(a + b + d) + (c + e)"
   138    "a + b + c + d + e" --> "(a + b + d) + (c + e)"
   166      (K (rewrite_goals_tac ac
   165      (K (rewrite_goals_tac ac
   167          THEN rtac Drule.reflexive_thm 1))
   166          THEN rtac Drule.reflexive_thm 1))
   168  end
   167  end
   169 
   168 
   170 (* instance for unions *)
   169 (* instance for unions *)
   171 fun regroup_union_conv t = regroup_conv @{const_name Set.empty} @{const_name Lattices.sup}
   170 val regroup_union_conv =
   172   (map (fn t => t RS eq_reflection) (@{thms Un_ac} @
   171   regroup_conv @{const_name Set.empty} @{const_name Lattices.sup}
   173                                      @{thms Un_empty_right} @
   172     (map (fn t => t RS eq_reflection)
   174                                      @{thms Un_empty_left})) t
   173       (@{thms Un_ac} @ @{thms Un_empty_right} @ @{thms Un_empty_left}))
   175 
   174 
   176 
   175 
   177 end
   176 end