src/HOL/Prod.thy
changeset 1068 e0f2dffab506
parent 972 e61b058d58d2
child 1081 884c6ef06fbf
equal deleted inserted replaced
1067:00ed040f66e1 1068:e0f2dffab506
    32   split         :: "[['a, 'b] => 'c, 'a * 'b] => 'c"
    32   split         :: "[['a, 'b] => 'c, 'a * 'b] => 'c"
    33   prod_fun      :: "['a => 'b, 'c => 'd, 'a * 'c] => 'b * 'd"
    33   prod_fun      :: "['a => 'b, 'c => 'd, 'a * 'c] => 'b * 'd"
    34   Pair          :: "['a, 'b] => 'a * 'b"
    34   Pair          :: "['a, 'b] => 'a * 'b"
    35   Sigma         :: "['a set, 'a => 'b set] => ('a * 'b) set"
    35   Sigma         :: "['a set, 'a => 'b set] => ('a * 'b) set"
    36 
    36 
       
    37 (** Patterns -- extends pre-defined type "pttrn" used in abstractions **)
       
    38 types pttrns
       
    39 
    37 syntax
    40 syntax
    38   "@Tuple"      :: "['a, args] => 'a * 'b"            ("(1'(_,/ _'))")
    41   "@Tuple"      :: "['a, args] => 'a * 'b"            ("(1'(_,/ _'))")
       
    42 
       
    43   "@pttrn"  :: "pttrns => pttrn"            ("'(_')")
       
    44   ""        :: " pttrn           => pttrns" ("_")
       
    45   "@pttrns" :: "[pttrn,pttrns]   => pttrns" ("_,/_")
    39 
    46 
    40 translations
    47 translations
    41   "(x, y, z)"   == "(x, (y, z))"
    48   "(x, y, z)"   == "(x, (y, z))"
    42   "(x, y)"      == "Pair x y"
    49   "(x, y)"      == "Pair x y"
       
    50 
       
    51   "%(x,y,zs).b"   => "split(%x (y,zs).b)"
       
    52   "%(x,y).b"      => "split(%x y.b)"
       
    53 (* The <= direction fails if split has more than one argument because
       
    54    ast-matching fails. Otherwise it would work fine *)
    43 
    55 
    44 defs
    56 defs
    45   Pair_def      "Pair a b == Abs_Prod(Pair_Rep a b)"
    57   Pair_def      "Pair a b == Abs_Prod(Pair_Rep a b)"
    46   fst_def       "fst(p) == @a. ? b. p = (a, b)"
    58   fst_def       "fst(p) == @a. ? b. p = (a, b)"
    47   snd_def       "snd(p) == @b. ? a. p = (a, b)"
    59   snd_def       "snd(p) == @b. ? a. p = (a, b)"
    61 
    73 
    62 defs
    74 defs
    63   Unity_def     "() == Abs_Unit(True)"
    75   Unity_def     "() == Abs_Unit(True)"
    64 
    76 
    65 end
    77 end
       
    78 
       
    79 ML
       
    80 
       
    81 local open Syntax
       
    82 
       
    83 fun pttrn s = const"@pttrn" $ s;
       
    84 fun pttrns s t = const"@pttrns" $ s $ t;
       
    85 
       
    86 fun split2(Abs(x,T,t)) =
       
    87       let val (pats,u) = split1 t
       
    88       in (pttrns (Free(x,T)) pats, subst_bounds([free x],u)) end
       
    89   | split2(Const("split",_) $ r) =
       
    90       let val (pats,s) = split2(r)
       
    91           val (pats2,t) = split1(s)
       
    92       in (pttrns (pttrn pats) pats2, t) end
       
    93 and split1(Abs(x,T,t)) =  (Free(x,T), subst_bounds([free x],t))
       
    94   | split1(Const("split",_)$t) = split2(t);
       
    95 
       
    96 fun split_tr'(t::args) =
       
    97   let val (pats,ft) = split2(t)
       
    98   in case args of
       
    99        [] => const"_abs" $ pttrn pats $ ft
       
   100      | arg::rest =>
       
   101          list_comb(const"_Let"$(const"_bind"$(pttrn pats)$arg)$ft, rest)
       
   102   end
       
   103 
       
   104 in
       
   105 
       
   106 val print_translation = [("split", split_tr')];
       
   107 
       
   108 end;