src/HOL/Product_Type.thy
changeset 35115 446c5063e4fd
parent 34900 9b12b0824bfe
child 35364 b8c62d60195c
equal deleted inserted replaced
35114:b1fd1d756e20 35115:446c5063e4fd
   178   "_pattern"    :: "[pttrn, patterns] => pttrn"         ("'(_,/ _')")
   178   "_pattern"    :: "[pttrn, patterns] => pttrn"         ("'(_,/ _')")
   179   ""            :: "pttrn => patterns"                  ("_")
   179   ""            :: "pttrn => patterns"                  ("_")
   180   "_patterns"   :: "[pttrn, patterns] => patterns"      ("_,/ _")
   180   "_patterns"   :: "[pttrn, patterns] => patterns"      ("_,/ _")
   181 
   181 
   182 translations
   182 translations
   183   "(x, y)"       == "Pair x y"
   183   "(x, y)" == "CONST Pair x y"
   184   "_tuple x (_tuple_args y z)" == "_tuple x (_tuple_arg (_tuple y z))"
   184   "_tuple x (_tuple_args y z)" == "_tuple x (_tuple_arg (_tuple y z))"
   185   "%(x,y,zs).b"  == "split(%x (y,zs).b)"
   185   "%(x, y, zs). b" == "CONST split (%x (y, zs). b)"
   186   "%(x,y).b"     == "split(%x y. b)"
   186   "%(x, y). b" == "CONST split (%x y. b)"
   187   "_abs (Pair x y) t" => "%(x,y).t"
   187   "_abs (CONST Pair x y) t" => "%(x, y). t"
   188   (* The last rule accommodates tuples in `case C ... (x,y) ... => ...'
   188   (* The last rule accommodates tuples in `case C ... (x,y) ... => ...'
   189      The (x,y) is parsed as `Pair x y' because it is logic, not pttrn *)
   189      The (x,y) is parsed as `Pair x y' because it is logic, not pttrn *)
   190 
   190 
   191 (* reconstructs pattern from (nested) splits, avoiding eta-contraction of body*)
   191 (*reconstruct pattern from (nested) splits, avoiding eta-contraction of body;
   192 (* works best with enclosing "let", if "let" does not avoid eta-contraction   *)
   192   works best with enclosing "let", if "let" does not avoid eta-contraction*)
   193 print_translation {*
   193 print_translation {*
   194 let fun split_tr' [Abs (x,T,t as (Abs abs))] =
   194 let
   195       (* split (%x y. t) => %(x,y) t *)
   195   fun split_tr' [Abs (x, T, t as (Abs abs))] =
   196       let val (y,t') = atomic_abs_tr' abs;
   196         (* split (%x y. t) => %(x,y) t *)
   197           val (x',t'') = atomic_abs_tr' (x,T,t');
   197         let
   198     
   198           val (y, t') = atomic_abs_tr' abs;
   199       in Syntax.const "_abs" $ (Syntax.const "_pattern" $x'$y) $ t'' end
   199           val (x', t'') = atomic_abs_tr' (x, T, t');
   200     | split_tr' [Abs (x,T,(s as Const ("split",_)$t))] =
   200         in
   201        (* split (%x. (split (%y z. t))) => %(x,y,z). t *)
   201           Syntax.const @{syntax_const "_abs"} $
   202        let val (Const ("_abs",_)$(Const ("_pattern",_)$y$z)$t') = split_tr' [t];
   202             (Syntax.const @{syntax_const "_pattern"} $ x' $ y) $ t''
   203            val (x',t'') = atomic_abs_tr' (x,T,t');
   203         end
   204        in Syntax.const "_abs"$ 
   204     | split_tr' [Abs (x, T, (s as Const (@{const_syntax split}, _) $ t))] =
   205            (Syntax.const "_pattern"$x'$(Syntax.const "_patterns"$y$z))$t'' end
   205         (* split (%x. (split (%y z. t))) => %(x,y,z). t *)
   206     | split_tr' [Const ("split",_)$t] =
   206         let
   207        (* split (split (%x y z. t)) => %((x,y),z). t *)   
   207           val Const (@{syntax_const "_abs"}, _) $
   208        split_tr' [(split_tr' [t])] (* inner split_tr' creates next pattern *)
   208             (Const (@{syntax_const "_pattern"}, _) $ y $ z) $ t' = split_tr' [t];
   209     | split_tr' [Const ("_abs",_)$x_y$(Abs abs)] =
   209           val (x', t'') = atomic_abs_tr' (x, T, t');
   210        (* split (%pttrn z. t) => %(pttrn,z). t *)
   210         in
   211        let val (z,t) = atomic_abs_tr' abs;
   211           Syntax.const @{syntax_const "_abs"} $
   212        in Syntax.const "_abs" $ (Syntax.const "_pattern" $x_y$z) $ t end
   212             (Syntax.const @{syntax_const "_pattern"} $ x' $
   213     | split_tr' _ =  raise Match;
   213               (Syntax.const @{syntax_const "_patterns"} $ y $ z)) $ t''
   214 in [("split", split_tr')]
   214         end
   215 end
   215     | split_tr' [Const (@{const_syntax split}, _) $ t] =
       
   216         (* split (split (%x y z. t)) => %((x, y), z). t *)
       
   217         split_tr' [(split_tr' [t])] (* inner split_tr' creates next pattern *)
       
   218     | split_tr' [Const (@{syntax_const "_abs"}, _) $ x_y $ Abs abs] =
       
   219         (* split (%pttrn z. t) => %(pttrn,z). t *)
       
   220         let val (z, t) = atomic_abs_tr' abs in
       
   221           Syntax.const @{syntax_const "_abs"} $
       
   222             (Syntax.const @{syntax_const "_pattern"} $ x_y $ z) $ t
       
   223         end
       
   224     | split_tr' _ = raise Match;
       
   225 in [(@{const_syntax split}, split_tr')] end
   216 *}
   226 *}
   217 
   227 
   218 (* print "split f" as "\<lambda>(x,y). f x y" and "split (\<lambda>x. f x)" as "\<lambda>(x,y). f x y" *) 
   228 (* print "split f" as "\<lambda>(x,y). f x y" and "split (\<lambda>x. f x)" as "\<lambda>(x,y). f x y" *) 
   219 typed_print_translation {*
   229 typed_print_translation {*
   220 let
   230 let
   221   fun split_guess_names_tr' _ T [Abs (x,_,Abs _)] = raise Match
   231   fun split_guess_names_tr' _ T [Abs (x, _, Abs _)] = raise Match
   222     | split_guess_names_tr' _ T  [Abs (x,xT,t)] =
   232     | split_guess_names_tr' _ T [Abs (x, xT, t)] =
   223         (case (head_of t) of
   233         (case (head_of t) of
   224            Const ("split",_) => raise Match
   234           Const (@{const_syntax split}, _) => raise Match
   225          | _ => let 
   235         | _ =>
   226                   val (_::yT::_) = binder_types (domain_type T) handle Bind => raise Match;
   236           let 
   227                   val (y,t') = atomic_abs_tr' ("y",yT,(incr_boundvars 1 t)$Bound 0); 
   237             val (_ :: yT :: _) = binder_types (domain_type T) handle Bind => raise Match;
   228                   val (x',t'') = atomic_abs_tr' (x,xT,t');
   238             val (y, t') = atomic_abs_tr' ("y", yT, incr_boundvars 1 t $ Bound 0);
   229                 in Syntax.const "_abs" $ (Syntax.const "_pattern" $x'$y) $ t'' end)
   239             val (x', t'') = atomic_abs_tr' (x, xT, t');
       
   240           in
       
   241             Syntax.const @{syntax_const "_abs"} $
       
   242               (Syntax.const @{syntax_const "_pattern"} $ x' $ y) $ t''
       
   243           end)
   230     | split_guess_names_tr' _ T [t] =
   244     | split_guess_names_tr' _ T [t] =
   231        (case (head_of t) of
   245         (case head_of t of
   232            Const ("split",_) => raise Match 
   246           Const (@{const_syntax split}, _) => raise Match
   233          | _ => let 
   247         | _ =>
   234                   val (xT::yT::_) = binder_types (domain_type T) handle Bind => raise Match;
   248           let
   235                   val (y,t') = 
   249             val (xT :: yT :: _) = binder_types (domain_type T) handle Bind => raise Match;
   236                         atomic_abs_tr' ("y",yT,(incr_boundvars 2 t)$Bound 1$Bound 0); 
   250             val (y, t') = atomic_abs_tr' ("y", yT, incr_boundvars 2 t $ Bound 1 $ Bound 0);
   237                   val (x',t'') = atomic_abs_tr' ("x",xT,t');
   251             val (x', t'') = atomic_abs_tr' ("x", xT, t');
   238                 in Syntax.const "_abs" $ (Syntax.const "_pattern" $x'$y) $ t'' end)
   252           in
       
   253             Syntax.const @{syntax_const "_abs"} $
       
   254               (Syntax.const @{syntax_const "_pattern"} $ x' $ y) $ t''
       
   255           end)
   239     | split_guess_names_tr' _ _ _ = raise Match;
   256     | split_guess_names_tr' _ _ _ = raise Match;
   240 in [("split", split_guess_names_tr')]
   257 in [(@{const_syntax split}, split_guess_names_tr')] end
   241 end 
       
   242 *}
   258 *}
   243 
   259 
   244 
   260 
   245 text {* Towards a datatype declaration *}
   261 text {* Towards a datatype declaration *}
   246 
   262 
   853 
   869 
   854 notation (HTML output)
   870 notation (HTML output)
   855   Times  (infixr "\<times>" 80)
   871   Times  (infixr "\<times>" 80)
   856 
   872 
   857 syntax
   873 syntax
   858   "@Sigma" ::"[pttrn, 'a set, 'b set] => ('a * 'b) set" ("(3SIGMA _:_./ _)" [0, 0, 10] 10)
   874   "_Sigma" :: "[pttrn, 'a set, 'b set] => ('a * 'b) set"  ("(3SIGMA _:_./ _)" [0, 0, 10] 10)
   859 
       
   860 translations
   875 translations
   861   "SIGMA x:A. B" == "Product_Type.Sigma A (%x. B)"
   876   "SIGMA x:A. B" == "CONST Sigma A (%x. B)"
   862 
   877 
   863 lemma SigmaI [intro!]: "[| a:A;  b:B(a) |] ==> (a,b) : Sigma A B"
   878 lemma SigmaI [intro!]: "[| a:A;  b:B(a) |] ==> (a,b) : Sigma A B"
   864   by (unfold Sigma_def) blast
   879   by (unfold Sigma_def) blast
   865 
   880 
   866 lemma SigmaE [elim!]:
   881 lemma SigmaE [elim!]: