src/Pure/IsaPlanner/rw_tools.ML
changeset 15481 fc075ae929e4
child 15531 08c8dad8e399
equal deleted inserted replaced
15480:cb3612cc41a3 15481:fc075ae929e4
       
     1 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) 
       
     2 (*  Title:      sys/rw_tools.ML
       
     3     Author:     Lucas Dixon, University of Edinburgh
       
     4                 lucas.dixon@ed.ac.uk
       
     5     Created:    28 May 2004
       
     6 *)
       
     7 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) 
       
     8 (*  DESCRIPTION:
       
     9 
       
    10     term related tools used for rewriting
       
    11 
       
    12 *)   
       
    13 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *)
       
    14 
       
    15 signature RWTOOLS =
       
    16 sig
       
    17 end;
       
    18 
       
    19 structure RWTools 
       
    20 = struct
       
    21 
       
    22 (* THINKABOUT: don't need this: should be able to generate the paired 
       
    23    NsTs directly ? --already implemented as ~~
       
    24 fun join_lists ([],[]) = []
       
    25   | join_lists (x::xs, y::ys) = (x,y) :: (join_lists (xs,ys))
       
    26   | join_lists (_, _) = raise ERROR_MESSAGE "join_lists: unequal size lists";
       
    27  *)
       
    28 
       
    29 (* fake free variable names for locally bound variables - these work
       
    30 as placeholders. *)
       
    31 fun dest_fake_bound_name n = 
       
    32     case (explode n) of 
       
    33       (":" :: realchars) => implode realchars
       
    34     | _ => n;
       
    35 fun is_fake_bound_name n = (hd (explode n) = ":");
       
    36 fun mk_fake_bound_name n = ":" ^ n;
       
    37 
       
    38 
       
    39 
       
    40 (* fake free variable names for local meta variables - these work
       
    41 as placeholders. *)
       
    42 fun dest_fake_fix_name n = 
       
    43     case (explode n) of 
       
    44       ("@" :: realchars) => implode realchars
       
    45     | _ => n;
       
    46 fun is_fake_fix_name n = (hd (explode n) = "@");
       
    47 fun mk_fake_fix_name n = "@" ^ n;
       
    48 
       
    49 
       
    50 
       
    51 (* fake free variable names for meta level bound variables *)
       
    52 fun dest_fake_all_name n = 
       
    53     case (explode n) of 
       
    54       ("+" :: realchars) => implode realchars
       
    55     | _ => n;
       
    56 fun is_fake_all_name n = (hd (explode n) = "+");
       
    57 fun mk_fake_all_name n = "+" ^ n;
       
    58 
       
    59 
       
    60 
       
    61 
       
    62 (* Ys and Ts not used, Ns are real names of faked local bounds, the
       
    63 idea is that this will be mapped to free variables thus if a free
       
    64 variable is a faked local bound then we change it to being a meta
       
    65 variable so that it can later be instantiated *)
       
    66 (* FIXME: rename this - avoid the word fix! *)
       
    67 (* note we are not really "fix"'ing the free, more like making it variable! *)
       
    68 fun trymkvar_of_fakefree (Ns, Ts) Ys (n,ty) = 
       
    69     if (dest_fake_bound_name n) mem Ns then Var((n,0),ty) else Free (n,ty);
       
    70 
       
    71 (* make a var into a fixed free (ie prefixed with "@") *)
       
    72 fun mk_fakefixvar Ts ((n,i),ty) = Free(mk_fake_fix_name n, ty);
       
    73 
       
    74 
       
    75 (* mk_frees_bound: string list -> Term.term -> Term.term *)
       
    76 (* This function changes free variables to being represented as bound
       
    77 variables if the free's variable name is in the given list. The debruijn 
       
    78 index is simply the position in the list *)
       
    79 (* THINKABOUT: danger of an existing free variable with the same name: fix
       
    80 this so that name conflict are avoided automatically! In the meantime,
       
    81 don't have free variables named starting with a ":" *)
       
    82 fun bounds_of_fakefrees Ys (a $ b) = 
       
    83     (bounds_of_fakefrees Ys a) $ (bounds_of_fakefrees Ys b)
       
    84   | bounds_of_fakefrees Ys (Abs(n,ty,t)) = 
       
    85     Abs(n,ty, bounds_of_fakefrees (n::Ys) t)
       
    86   | bounds_of_fakefrees Ys (Free (n,ty)) = 
       
    87     let fun try_mk_bound_of_free (i,[]) = Free (n,ty)
       
    88           | try_mk_bound_of_free (i,(y::ys)) = 
       
    89             if n = y then Bound i else try_mk_bound_of_free (i+1,ys)
       
    90     in try_mk_bound_of_free (0,Ys) end
       
    91   | bounds_of_fakefrees Ys t = t;
       
    92 
       
    93 
       
    94 (* map a function f onto each free variables *)
       
    95 fun map_to_frees f Ys (a $ b) = 
       
    96     (map_to_frees f Ys a) $ (map_to_frees f Ys b)
       
    97   | map_to_frees f Ys (Abs(n,ty,t)) = 
       
    98     Abs(n,ty, map_to_frees f ((n,ty)::Ys) t)
       
    99   | map_to_frees f Ys (Free a) = 
       
   100     f Ys a
       
   101   | map_to_frees f Ys t = t;
       
   102 
       
   103 
       
   104 (* map a function f onto each meta variable  *)
       
   105 fun map_to_vars f Ys (a $ b) = 
       
   106     (map_to_vars f Ys a) $ (map_to_vars f Ys b)
       
   107   | map_to_vars f Ys (Abs(n,ty,t)) = 
       
   108     Abs(n,ty, map_to_vars f ((n,ty)::Ys) t)
       
   109   | map_to_vars f Ys (Var a) = 
       
   110     f Ys a
       
   111   | map_to_vars f Ys t = t;
       
   112 
       
   113 (* map a function f onto each free variables *)
       
   114 fun map_to_alls f (Const("all",allty) $ Abs(n,ty,t)) = 
       
   115     let val (n2,ty2) = f (n,ty) 
       
   116     in (Const("all",allty) $ Abs(n2,ty2,map_to_alls f t)) end
       
   117   | map_to_alls f x = x;
       
   118 
       
   119 (* map a function f to each type variable in a term *)
       
   120 (* implicit arg: term *)
       
   121 fun map_to_term_tvars f =
       
   122     Term.map_term_types (fn TVar(ix,ty) => f (ix,ty) | x => x);
       
   123 
       
   124 
       
   125 
       
   126 (* what if a param desn't occur in the concl? think about! Note: This
       
   127 simply fixes meta level univ bound vars as Frees.  At the end, we will
       
   128 change them back to schematic vars that will then unify
       
   129 appropriactely, ie with unfake_vars *)
       
   130 fun fake_concl_of_goal gt i = 
       
   131     let 
       
   132       val prems = Logic.strip_imp_prems gt
       
   133       val sgt = nth_elem (i - 1, prems)
       
   134 
       
   135       val tbody = Logic.strip_imp_concl (Term.strip_all_body sgt)
       
   136       val tparams = Term.strip_all_vars sgt
       
   137 
       
   138       val fakefrees = map (fn (n, ty) => Free(mk_fake_all_name n, ty)) 
       
   139                           tparams
       
   140     in
       
   141       Term.subst_bounds (rev fakefrees,tbody)
       
   142     end;
       
   143 
       
   144 (* what if a param desn't occur in the concl? think about! Note: This
       
   145 simply fixes meta level univ bound vars as Frees.  At the end, we will
       
   146 change them back to schematic vars that will then unify
       
   147 appropriactely, ie with unfake_vars *)
       
   148 fun fake_goal gt i = 
       
   149     let 
       
   150       val prems = Logic.strip_imp_prems gt
       
   151       val sgt = nth_elem (i - 1, prems)
       
   152 
       
   153       val tbody = Term.strip_all_body sgt
       
   154       val tparams = Term.strip_all_vars sgt
       
   155 
       
   156       val fakefrees = map (fn (n, ty) => Free(mk_fake_all_name n, ty)) 
       
   157                           tparams
       
   158     in
       
   159       Term.subst_bounds (rev fakefrees,tbody)
       
   160     end;
       
   161 
       
   162 
       
   163 (* hand written - for some reason the Isabelle version in drule is broken!
       
   164 Example? something to do with Bin Yangs examples? 
       
   165  *)
       
   166 fun rename_term_bvars ns (Abs(s,ty,t)) = 
       
   167     let val s2opt = Library.find_first (fn (x,y) => s = x) ns
       
   168     in case s2opt of 
       
   169          None => (Abs(s,ty,rename_term_bvars  ns t))
       
   170        | Some (_,s2) => Abs(s2,ty, rename_term_bvars ns t) end
       
   171   | rename_term_bvars ns (a$b) = 
       
   172     (rename_term_bvars ns a) $ (rename_term_bvars ns b)
       
   173   | rename_term_bvars _ x = x;
       
   174 
       
   175 fun rename_thm_bvars ns th = 
       
   176     let val t = Thm.prop_of th 
       
   177     in Thm.rename_boundvars t (rename_term_bvars ns t) th end;
       
   178 
       
   179 (* Finish this to show how it breaks! (raises the exception): 
       
   180 
       
   181 exception rename_thm_bvars_exp of ((string * string) list * Thm.thm)
       
   182 
       
   183     Drule.rename_bvars ns th 
       
   184     handle TERM _ => raise rename_thm_bvars_exp (ns, th); 
       
   185 *)
       
   186 
       
   187 end;