src/HOL/Tools/hologic.ML
changeset 36692 54b64d4ad524
parent 35625 9c818cab0dd0
child 37145 01aa36932739
equal deleted inserted replaced
36674:d95f39448121 36692:54b64d4ad524
   354 fun ptuple_err s = raise TERM (s ^ ": inconsistent use of nested products", []);
   354 fun ptuple_err s = raise TERM (s ^ ": inconsistent use of nested products", []);
   355 
   355 
   356 fun mk_ptupleT ps =
   356 fun mk_ptupleT ps =
   357   let
   357   let
   358     fun mk p Ts =
   358     fun mk p Ts =
   359       if p mem ps then
   359       if member (op =) ps p then
   360         let
   360         let
   361           val (T, Ts') = mk (1::p) Ts;
   361           val (T, Ts') = mk (1::p) Ts;
   362           val (U, Ts'') = mk (2::p) Ts'
   362           val (U, Ts'') = mk (2::p) Ts'
   363         in (mk_prodT (T, U), Ts'') end
   363         in (mk_prodT (T, U), Ts'') end
   364       else (hd Ts, tl Ts)
   364       else (hd Ts, tl Ts)
   365   in fst o mk [] end;
   365   in fst o mk [] end;
   366 
   366 
   367 fun strip_ptupleT ps =
   367 fun strip_ptupleT ps =
   368   let
   368   let
   369     fun factors p T = if p mem ps then (case T of
   369     fun factors p T = if member (op =) ps p then (case T of
   370         Type ("*", [T1, T2]) =>
   370         Type ("*", [T1, T2]) =>
   371           factors (1::p) T1 @ factors (2::p) T2
   371           factors (1::p) T1 @ factors (2::p) T2
   372       | _ => ptuple_err "strip_ptupleT") else [T]
   372       | _ => ptuple_err "strip_ptupleT") else [T]
   373   in factors [] end;
   373   in factors [] end;
   374 
   374 
   380   in factors [] end;
   380   in factors [] end;
   381 
   381 
   382 fun mk_ptuple ps =
   382 fun mk_ptuple ps =
   383   let
   383   let
   384     fun mk p T ts =
   384     fun mk p T ts =
   385       if p mem ps then (case T of
   385       if member (op =) ps p then (case T of
   386           Type ("*", [T1, T2]) =>
   386           Type ("*", [T1, T2]) =>
   387             let
   387             let
   388               val (t, ts') = mk (1::p) T1 ts;
   388               val (t, ts') = mk (1::p) T1 ts;
   389               val (u, ts'') = mk (2::p) T2 ts'
   389               val (u, ts'') = mk (2::p) T2 ts'
   390             in (pair_const T1 T2 $ t $ u, ts'') end
   390             in (pair_const T1 T2 $ t $ u, ts'') end
   392       else (hd ts, tl ts)
   392       else (hd ts, tl ts)
   393   in fst oo mk [] end;
   393   in fst oo mk [] end;
   394 
   394 
   395 fun strip_ptuple ps =
   395 fun strip_ptuple ps =
   396   let
   396   let
   397     fun dest p t = if p mem ps then (case t of
   397     fun dest p t = if member (op =) ps p then (case t of
   398         Const ("Pair", _) $ t $ u =>
   398         Const ("Pair", _) $ t $ u =>
   399           dest (1::p) t @ dest (2::p) u
   399           dest (1::p) t @ dest (2::p) u
   400       | _ => ptuple_err "strip_ptuple") else [t]
   400       | _ => ptuple_err "strip_ptuple") else [t]
   401   in dest [] end;
   401   in dest [] end;
   402 
   402 
   411   with result type T.  The call creates a new term expecting one argument
   411   with result type T.  The call creates a new term expecting one argument
   412   of type S.*)
   412   of type S.*)
   413 fun mk_psplits ps T T3 u =
   413 fun mk_psplits ps T T3 u =
   414   let
   414   let
   415     fun ap ((p, T) :: pTs) =
   415     fun ap ((p, T) :: pTs) =
   416           if p mem ps then (case T of
   416           if member (op =) ps p then (case T of
   417               Type ("*", [T1, T2]) =>
   417               Type ("*", [T1, T2]) =>
   418                 split_const (T1, T2, map snd pTs ---> T3) $
   418                 split_const (T1, T2, map snd pTs ---> T3) $
   419                   ap ((1::p, T1) :: (2::p, T2) :: pTs)
   419                   ap ((1::p, T1) :: (2::p, T2) :: pTs)
   420             | _ => ptuple_err "mk_psplits")
   420             | _ => ptuple_err "mk_psplits")
   421           else Abs ("x", T, ap pTs)
   421           else Abs ("x", T, ap pTs)