src/HOL/Record.thy
changeset 11833 475f772ab643
parent 11826 2203c7f9ec40
child 11956 b814360b0267
equal deleted inserted replaced
11832:8fca3665d1ee 11833:475f772ab643
    11 
    11 
    12 subsection {* Abstract product types *}
    12 subsection {* Abstract product types *}
    13 
    13 
    14 constdefs
    14 constdefs
    15   product_type :: "('p => 'a * 'b) => ('a * 'b => 'p) =>
    15   product_type :: "('p => 'a * 'b) => ('a * 'b => 'p) =>
    16     ('a => 'b => 'p) => ('p \<Rightarrow> 'a) => ('p => 'b) => bool"
    16     ('a => 'b => 'p) => ('p => 'a) => ('p => 'b) => bool"
    17   "product_type Rep Abs pair dest1 dest2 ==
    17   "product_type Rep Abs pair dest1 dest2 ==
    18     type_definition Rep Abs UNIV \<and>
    18     type_definition Rep Abs UNIV \<and>
    19     pair = (\<lambda>a b. Abs (a, b)) \<and>
    19     pair = (\<lambda>a b. Abs (a, b)) \<and>
    20     dest1 = (\<lambda>p. fst (Rep p)) \<and>
    20     dest1 = (\<lambda>p. fst (Rep p)) \<and>
    21     dest2 = (\<lambda>p. snd (Rep p))"
    21     dest2 = (\<lambda>p. snd (Rep p))"
    22 
    22 
    23 lemma product_typeI:
    23 lemma product_typeI:
    24   "type_definition Rep Abs UNIV ==>
    24   "type_definition Rep Abs UNIV ==>
    25     pair == \<lambda>a b. Abs (a, b) ==>
    25     pair == \<lambda>a b. Abs (a, b) ==>
    26     dest1 == (\<lambda>p. fst (Rep p)) \<Longrightarrow>
    26     dest1 == (\<lambda>p. fst (Rep p)) ==>
    27     dest2 == (\<lambda>p. snd (Rep p)) \<Longrightarrow>
    27     dest2 == (\<lambda>p. snd (Rep p)) ==>
    28     product_type Rep Abs pair dest1 dest2"
    28     product_type Rep Abs pair dest1 dest2"
    29   by (simp add: product_type_def)
    29   by (simp add: product_type_def)
    30 
    30 
    31 lemma product_type_typedef:
    31 lemma product_type_typedef:
    32     "product_type Rep Abs pair dest1 dest2 ==> type_definition Rep Abs UNIV"
    32     "product_type Rep Abs pair dest1 dest2 ==> type_definition Rep Abs UNIV"
    91   qed
    91   qed
    92 qed
    92 qed
    93 
    93 
    94 theorem product_type_cases [cases set: product_type]:
    94 theorem product_type_cases [cases set: product_type]:
    95   "product_type Rep Abs pair dest1 dest2 ==>
    95   "product_type Rep Abs pair dest1 dest2 ==>
    96     (!!x y. p = pair x y \<Longrightarrow> C) ==> C"
    96     (!!x y. p = pair x y ==> C) ==> C"
    97 proof -
    97 proof -
    98   assume prod_type: "product_type Rep Abs pair dest1 dest2"
    98   assume prod_type: "product_type Rep Abs pair dest1 dest2"
    99   assume "!!x y. p = pair x y \<Longrightarrow> C"
    99   assume "!!x y. p = pair x y ==> C"
   100   with prod_type show C
   100   with prod_type show C
   101     by (induct p) (simp only: product_type_inject [OF prod_type], blast)
   101     by (induct p) (simp only: product_type_inject [OF prod_type], blast)
   102 qed
   102 qed
   103 
   103 
   104 theorem product_type_surjective_pairing:
   104 theorem product_type_surjective_pairing:
   110     (simp add: product_type_conv1 [OF rule_context] product_type_conv2 [OF rule_context])
   110     (simp add: product_type_conv1 [OF rule_context] product_type_conv2 [OF rule_context])
   111 qed
   111 qed
   112 
   112 
   113 theorem product_type_split_paired_all:
   113 theorem product_type_split_paired_all:
   114   "product_type Rep Abs pair dest1 dest2 ==>
   114   "product_type Rep Abs pair dest1 dest2 ==>
   115   (\<And>x. PROP P x) \<equiv> (\<And>a b. PROP P (pair a b))"
   115   (!!x. PROP P x) == (!!a b. PROP P (pair a b))"
   116 proof
   116 proof
   117   fix a b
   117   fix a b
   118   assume "!!x. PROP P x"
   118   assume "!!x. PROP P x"
   119   thus "PROP P (pair a b)" .
   119   thus "PROP P (pair a b)" .
   120 next
   120 next
   124   hence "PROP P (pair (dest1 x) (dest2 x))" .
   124   hence "PROP P (pair (dest1 x) (dest2 x))" .
   125   thus "PROP P x" by (simp only: product_type_surjective_pairing [OF rule_context, symmetric])
   125   thus "PROP P x" by (simp only: product_type_surjective_pairing [OF rule_context, symmetric])
   126 qed
   126 qed
   127 
   127 
   128 
   128 
   129 text {* \medskip Type class for record extensions. *}
   129 subsection {* Type class for record extensions *}
   130 
   130 
   131 axclass more < "term"
   131 axclass more < "term"
   132 instance unit :: more ..
   132 instance unit :: more ..
   133 
   133 
   134 
   134 
   135 subsection {* Record package setup *}
   135 subsection {* Concrete record syntax *}
   136 
       
   137 use "Tools/record_package.ML"
       
   138 setup RecordPackage.setup
       
   139 
       
   140 
       
   141 subsection {* Concrete syntax *}
       
   142 
   136 
   143 nonterminals
   137 nonterminals
   144   ident field_type field_types field fields update updates
   138   ident field_type field_types field fields update updates
   145 
   139 
   146 syntax
   140 syntax
   170   "_record_type_scheme" :: "[field_types, type] => type"        ("(3\<lparr>_,/ (2\<dots> ::/ _)\<rparr>)")
   164   "_record_type_scheme" :: "[field_types, type] => type"        ("(3\<lparr>_,/ (2\<dots> ::/ _)\<rparr>)")
   171   "_record"             :: "fields => 'a"                               ("(3\<lparr>_\<rparr>)")
   165   "_record"             :: "fields => 'a"                               ("(3\<lparr>_\<rparr>)")
   172   "_record_scheme"      :: "[fields, 'a] => 'a"                 ("(3\<lparr>_,/ (2\<dots> =/ _)\<rparr>)")
   166   "_record_scheme"      :: "[fields, 'a] => 'a"                 ("(3\<lparr>_,/ (2\<dots> =/ _)\<rparr>)")
   173   "_record_update"      :: "['a, updates] => 'b"                ("_/(3\<lparr>_\<rparr>)" [900,0] 900)
   167   "_record_update"      :: "['a, updates] => 'b"                ("_/(3\<lparr>_\<rparr>)" [900,0] 900)
   174 
   168 
   175 parse_translation {*
   169 
   176   let
   170 subsection {* Package setup *}
   177     fun update_name_tr (Free (x, T) :: ts) =
   171 
   178           Term.list_comb (Free (suffix RecordPackage.updateN x, T), ts)
   172 use "Tools/record_package.ML"
   179       | update_name_tr (Const (x, T) :: ts) =
   173 setup RecordPackage.setup
   180           Term.list_comb (Const (suffix RecordPackage.updateN x, T), ts)
       
   181       | update_name_tr (((c as Const ("_constrain", _)) $ t $ ty) :: ts) =
       
   182           Term.list_comb (c $ update_name_tr [t] $
       
   183             (Syntax.const "fun" $ ty $ Syntax.const "dummy"), ts)
       
   184       | update_name_tr ts = raise TERM ("update_name_tr", ts);
       
   185   in [("_update_name", update_name_tr)] end
       
   186 *}
       
   187 
   174 
   188 end
   175 end