src/Provers/splitter.ML
changeset 13157 4a4599f78f18
parent 10821 dcb75538f542
child 13855 644692eca537
equal deleted inserted replaced
13156:4597080b1947 13157:4a4599f78f18
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Tobias Nipkow
     3     Author:     Tobias Nipkow
     4     Copyright   1995  TU Munich
     4     Copyright   1995  TU Munich
     5 
     5 
     6 Generic case-splitter, suitable for most logics.
     6 Generic case-splitter, suitable for most logics.
       
     7 Deals with equalities of the form ?P(f args) = ...
       
     8 where "f args" must be a first-order term without duplicate variables.
     7 *)
     9 *)
     8 
    10 
     9 infix 4 addsplits delsplits;
    11 infix 4 addsplits delsplits;
    10 
    12 
    11 signature SPLITTER_DATA =
    13 signature SPLITTER_DATA =
   192           n   : number of arguments expected by Const(key,...)
   194           n   : number of arguments expected by Const(key,...)
   193    Ts   : types of parameters
   195    Ts   : types of parameters
   194    t    : the term to be scanned
   196    t    : the term to be scanned
   195 ******************************************************************************)
   197 ******************************************************************************)
   196 
   198 
       
   199 (* Simplified first-order matching;
       
   200    assumes that all Vars in the pattern are distinct;
       
   201    see Pure/pattern.ML for the full version;
       
   202 *)
       
   203 local
       
   204 exception MATCH
       
   205 in
       
   206 fun typ_match tsig args = (Type.typ_match tsig args)
       
   207                           handle Type.TYPE_MATCH => raise MATCH;
       
   208 fun fomatch tsig args =
       
   209   let
       
   210     fun mtch tyinsts = fn
       
   211         (Ts,Var(_,T), t)  => typ_match tsig (tyinsts, (T, fastype_of1(Ts,t)))
       
   212       | (_,Free (a,T), Free (b,U)) =>
       
   213           if a=b then typ_match tsig (tyinsts,(T,U)) else raise MATCH
       
   214       | (_,Const (a,T), Const (b,U))  =>
       
   215           if a=b then typ_match tsig (tyinsts,(T,U)) else raise MATCH
       
   216       | (_,Bound i, Bound j)  =>  if  i=j  then tyinsts else raise MATCH
       
   217       | (Ts,Abs(_,T,t), Abs(_,U,u))  =>
       
   218           mtch (typ_match tsig (tyinsts,(T,U))) (U::Ts,t,u)
       
   219       | (Ts, f$t, g$u) => mtch (mtch tyinsts (Ts,f,g)) (Ts, t, u)
       
   220       | _ => raise MATCH
       
   221   in (mtch Vartab.empty args; true) handle MATCH => false end;
       
   222 end
       
   223 
   197 fun split_posns cmap sg Ts t =
   224 fun split_posns cmap sg Ts t =
   198   let
   225   let
   199     val T' = fastype_of1 (Ts, t);
   226     val T' = fastype_of1 (Ts, t);
   200     fun posns Ts pos apsns (Abs (_, T, t)) =
   227     fun posns Ts pos apsns (Abs (_, T, t)) =
   201           let val U = fastype_of1 (T::Ts,t)
   228           let val U = fastype_of1 (T::Ts,t)
   205             val (h, ts) = strip_comb t
   232             val (h, ts) = strip_comb t
   206             fun iter((i, a), t) = (i+1, (posns Ts (i::pos) apsns t) @ a);
   233             fun iter((i, a), t) = (i+1, (posns Ts (i::pos) apsns t) @ a);
   207             val a = case h of
   234             val a = case h of
   208               Const(c, cT) =>
   235               Const(c, cT) =>
   209                 let fun find [] = []
   236                 let fun find [] = []
   210                       | find ((gcT, thm, T, n)::tups) =
   237                       | find ((gcT, pat, thm, T, n)::tups) =
   211                           if Sign.typ_instance sg (cT, gcT)
   238                           let val t2 = list_comb (h, take (n, ts))
   212                           then
   239                           in if Sign.typ_instance sg (cT, gcT)
   213                             let val t2 = list_comb (h, take (n, ts))
   240                                 andalso fomatch (Sign.tsig_of sg) (Ts,pat,t2)
   214                             in mk_split_pack(thm,T,T',n,ts,apsns,pos,type_of1(Ts,t2),t2)
   241                              then mk_split_pack(thm,T,T',n,ts,apsns,pos,type_of1(Ts,t2),t2)
   215                             end
   242                              else find tups
   216                           else find tups
   243                           end
   217                 in find (assocs cmap c) end
   244                 in find (assocs cmap c) end
   218             | _ => []
   245             | _ => []
   219           in snd(foldl iter ((0, a), ts)) end
   246           in snd(foldl iter ((0, a), ts)) end
   220   in posns Ts [] [] t end;
   247   in posns Ts [] [] t end;
   221 
   248 
   302   | split_tac splits i =
   329   | split_tac splits i =
   303   let val splits = map Data.mk_eq splits;
   330   let val splits = map Data.mk_eq splits;
   304       fun add_thm(cmap,thm) =
   331       fun add_thm(cmap,thm) =
   305             (case concl_of thm of _$(t as _$lhs)$_ =>
   332             (case concl_of thm of _$(t as _$lhs)$_ =>
   306                (case strip_comb lhs of (Const(a,aT),args) =>
   333                (case strip_comb lhs of (Const(a,aT),args) =>
   307                   let val info = (aT,thm,fastype_of t,length args)
   334                   let val info = (aT,lhs,thm,fastype_of t,length args)
   308                   in case assoc(cmap,a) of
   335                   in case assoc(cmap,a) of
   309                        Some infos => overwrite(cmap,(a,info::infos))
   336                        Some infos => overwrite(cmap,(a,info::infos))
   310                      | None => (a,[info])::cmap
   337                      | None => (a,[info])::cmap
   311                   end
   338                   end
   312                 | _ => split_format_err())
   339                 | _ => split_format_err())