src/HOL/HOLCF/ex/Pattern_Match.thy
changeset 62175 8ffc4d0e652d
parent 61998 b66d2ca1f907
child 69216 1a52baa70aed
equal deleted inserted replaced
62174:fae6233c5f37 62175:8ffc4d0e652d
     1 (*  Title:      HOL/HOLCF/ex/Pattern_Match.thy
     1 (*  Title:      HOL/HOLCF/ex/Pattern_Match.thy
     2     Author:     Brian Huffman
     2     Author:     Brian Huffman
     3 *)
     3 *)
     4 
     4 
     5 section {* An experimental pattern-matching notation *}
     5 section \<open>An experimental pattern-matching notation\<close>
     6 
     6 
     7 theory Pattern_Match
     7 theory Pattern_Match
     8 imports HOLCF
     8 imports HOLCF
     9 begin
     9 begin
    10 
    10 
    11 default_sort pcpo
    11 default_sort pcpo
    12 
    12 
    13 text {* FIXME: Find a proper way to un-hide constants. *}
    13 text \<open>FIXME: Find a proper way to un-hide constants.\<close>
    14 
    14 
    15 abbreviation fail :: "'a match"
    15 abbreviation fail :: "'a match"
    16 where "fail \<equiv> Fixrec.fail"
    16 where "fail \<equiv> Fixrec.fail"
    17 
    17 
    18 abbreviation succeed :: "'a \<rightarrow> 'a match"
    18 abbreviation succeed :: "'a \<rightarrow> 'a match"
    19 where "succeed \<equiv> Fixrec.succeed"
    19 where "succeed \<equiv> Fixrec.succeed"
    20 
    20 
    21 abbreviation run :: "'a match \<rightarrow> 'a"
    21 abbreviation run :: "'a match \<rightarrow> 'a"
    22 where "run \<equiv> Fixrec.run"
    22 where "run \<equiv> Fixrec.run"
    23 
    23 
    24 subsection {* Fatbar combinator *}
    24 subsection \<open>Fatbar combinator\<close>
    25 
    25 
    26 definition
    26 definition
    27   fatbar :: "('a \<rightarrow> 'b match) \<rightarrow> ('a \<rightarrow> 'b match) \<rightarrow> ('a \<rightarrow> 'b match)" where
    27   fatbar :: "('a \<rightarrow> 'b match) \<rightarrow> ('a \<rightarrow> 'b match) \<rightarrow> ('a \<rightarrow> 'b match)" where
    28   "fatbar = (\<Lambda> a b x. a\<cdot>x +++ b\<cdot>x)"
    28   "fatbar = (\<Lambda> a b x. a\<cdot>x +++ b\<cdot>x)"
    29 
    29 
    51 lemma run_fatbar3: "m\<cdot>x = succeed\<cdot>y \<Longrightarrow> run\<cdot>((m \<parallel> ms)\<cdot>x) = y"
    51 lemma run_fatbar3: "m\<cdot>x = succeed\<cdot>y \<Longrightarrow> run\<cdot>((m \<parallel> ms)\<cdot>x) = y"
    52 by (simp add: fatbar_def)
    52 by (simp add: fatbar_def)
    53 
    53 
    54 lemmas run_fatbar_simps [simp] = run_fatbar1 run_fatbar2 run_fatbar3
    54 lemmas run_fatbar_simps [simp] = run_fatbar1 run_fatbar2 run_fatbar3
    55 
    55 
    56 subsection {* Bind operator for match monad *}
    56 subsection \<open>Bind operator for match monad\<close>
    57 
    57 
    58 definition match_bind :: "'a match \<rightarrow> ('a \<rightarrow> 'b match) \<rightarrow> 'b match" where
    58 definition match_bind :: "'a match \<rightarrow> ('a \<rightarrow> 'b match) \<rightarrow> 'b match" where
    59   "match_bind = (\<Lambda> m k. sscase\<cdot>(\<Lambda> _. fail)\<cdot>(fup\<cdot>k)\<cdot>(Rep_match m))"
    59   "match_bind = (\<Lambda> m k. sscase\<cdot>(\<Lambda> _. fail)\<cdot>(fup\<cdot>k)\<cdot>(Rep_match m))"
    60 
    60 
    61 lemma match_bind_simps [simp]:
    61 lemma match_bind_simps [simp]:
    64   "match_bind\<cdot>(succeed\<cdot>x)\<cdot>k = k\<cdot>x"
    64   "match_bind\<cdot>(succeed\<cdot>x)\<cdot>k = k\<cdot>x"
    65 unfolding match_bind_def fail_def succeed_def
    65 unfolding match_bind_def fail_def succeed_def
    66 by (simp_all add: cont_Rep_match cont_Abs_match
    66 by (simp_all add: cont_Rep_match cont_Abs_match
    67   Rep_match_strict Abs_match_inverse)
    67   Rep_match_strict Abs_match_inverse)
    68 
    68 
    69 subsection {* Case branch combinator *}
    69 subsection \<open>Case branch combinator\<close>
    70 
    70 
    71 definition
    71 definition
    72   branch :: "('a \<rightarrow> 'b match) \<Rightarrow> ('b \<rightarrow> 'c) \<rightarrow> ('a \<rightarrow> 'c match)" where
    72   branch :: "('a \<rightarrow> 'b match) \<Rightarrow> ('b \<rightarrow> 'c) \<rightarrow> ('a \<rightarrow> 'c match)" where
    73   "branch p \<equiv> \<Lambda> r x. match_bind\<cdot>(p\<cdot>x)\<cdot>(\<Lambda> y. succeed\<cdot>(r\<cdot>y))"
    73   "branch p \<equiv> \<Lambda> r x. match_bind\<cdot>(p\<cdot>x)\<cdot>(\<Lambda> y. succeed\<cdot>(r\<cdot>y))"
    74 
    74 
    79 by (simp_all add: branch_def)
    79 by (simp_all add: branch_def)
    80 
    80 
    81 lemma branch_succeed [simp]: "branch succeed\<cdot>r\<cdot>x = succeed\<cdot>(r\<cdot>x)"
    81 lemma branch_succeed [simp]: "branch succeed\<cdot>r\<cdot>x = succeed\<cdot>(r\<cdot>x)"
    82 by (simp add: branch_def)
    82 by (simp add: branch_def)
    83 
    83 
    84 subsection {* Cases operator *}
    84 subsection \<open>Cases operator\<close>
    85 
    85 
    86 definition
    86 definition
    87   cases :: "'a match \<rightarrow> 'a::pcpo" where
    87   cases :: "'a match \<rightarrow> 'a::pcpo" where
    88   "cases = Fixrec.run"
    88   "cases = Fixrec.run"
    89 
    89 
    90 text {* rewrite rules for cases *}
    90 text \<open>rewrite rules for cases\<close>
    91 
    91 
    92 lemma cases_strict [simp]: "cases\<cdot>\<bottom> = \<bottom>"
    92 lemma cases_strict [simp]: "cases\<cdot>\<bottom> = \<bottom>"
    93 by (simp add: cases_def)
    93 by (simp add: cases_def)
    94 
    94 
    95 lemma cases_fail [simp]: "cases\<cdot>fail = \<bottom>"
    95 lemma cases_fail [simp]: "cases\<cdot>fail = \<bottom>"
    96 by (simp add: cases_def)
    96 by (simp add: cases_def)
    97 
    97 
    98 lemma cases_succeed [simp]: "cases\<cdot>(succeed\<cdot>x) = x"
    98 lemma cases_succeed [simp]: "cases\<cdot>(succeed\<cdot>x) = x"
    99 by (simp add: cases_def)
    99 by (simp add: cases_def)
   100 
   100 
   101 subsection {* Case syntax *}
   101 subsection \<open>Case syntax\<close>
   102 
   102 
   103 nonterminal Case_pat and Case_syn and Cases_syn
   103 nonterminal Case_pat and Case_syn and Cases_syn
   104 
   104 
   105 syntax
   105 syntax
   106   "_Case_syntax":: "['a, Cases_syn] => 'b"               ("(Case _ of/ _)" 10)
   106   "_Case_syntax":: "['a, Cases_syn] => 'b"               ("(Case _ of/ _)" 10)
   114 
   114 
   115 translations
   115 translations
   116   "_Case_syntax x ms" == "CONST cases\<cdot>(ms\<cdot>x)"
   116   "_Case_syntax x ms" == "CONST cases\<cdot>(ms\<cdot>x)"
   117   "_Case2 m ms" == "m \<parallel> ms"
   117   "_Case2 m ms" == "m \<parallel> ms"
   118 
   118 
   119 text {* Parsing Case expressions *}
   119 text \<open>Parsing Case expressions\<close>
   120 
   120 
   121 syntax
   121 syntax
   122   "_pat" :: "'a"
   122   "_pat" :: "'a"
   123   "_variable" :: "'a"
   123   "_variable" :: "'a"
   124   "_noargs" :: "'a"
   124   "_noargs" :: "'a"
   126 translations
   126 translations
   127   "_Case1 p r" => "CONST branch (_pat p)\<cdot>(_variable p r)"
   127   "_Case1 p r" => "CONST branch (_pat p)\<cdot>(_variable p r)"
   128   "_variable (_args x y) r" => "CONST csplit\<cdot>(_variable x (_variable y r))"
   128   "_variable (_args x y) r" => "CONST csplit\<cdot>(_variable x (_variable y r))"
   129   "_variable _noargs r" => "CONST unit_when\<cdot>r"
   129   "_variable _noargs r" => "CONST unit_when\<cdot>r"
   130 
   130 
   131 parse_translation {*
   131 parse_translation \<open>
   132 (* rewrite (_pat x) => (succeed) *)
   132 (* rewrite (_pat x) => (succeed) *)
   133 (* rewrite (_variable x t) => (Abs_cfun (%x. t)) *)
   133 (* rewrite (_variable x t) => (Abs_cfun (%x. t)) *)
   134  [(@{syntax_const "_pat"}, fn _ => fn _ => Syntax.const @{const_syntax Fixrec.succeed}),
   134  [(@{syntax_const "_pat"}, fn _ => fn _ => Syntax.const @{const_syntax Fixrec.succeed}),
   135   Syntax_Trans.mk_binder_tr (@{syntax_const "_variable"}, @{const_syntax Abs_cfun})];
   135   Syntax_Trans.mk_binder_tr (@{syntax_const "_variable"}, @{const_syntax Abs_cfun})];
   136 *}
   136 \<close>
   137 
   137 
   138 text {* Printing Case expressions *}
   138 text \<open>Printing Case expressions\<close>
   139 
   139 
   140 syntax
   140 syntax
   141   "_match" :: "'a"
   141   "_match" :: "'a"
   142 
   142 
   143 print_translation {*
   143 print_translation \<open>
   144   let
   144   let
   145     fun dest_LAM (Const (@{const_syntax Rep_cfun},_) $ Const (@{const_syntax unit_when},_) $ t) =
   145     fun dest_LAM (Const (@{const_syntax Rep_cfun},_) $ Const (@{const_syntax unit_when},_) $ t) =
   146           (Syntax.const @{syntax_const "_noargs"}, t)
   146           (Syntax.const @{syntax_const "_noargs"}, t)
   147     |   dest_LAM (Const (@{const_syntax Rep_cfun},_) $ Const (@{const_syntax csplit},_) $ t) =
   147     |   dest_LAM (Const (@{const_syntax Rep_cfun},_) $ Const (@{const_syntax csplit},_) $ t) =
   148           let
   148           let
   163             Syntax.const @{syntax_const "_Case1"} $
   163             Syntax.const @{syntax_const "_Case1"} $
   164               (Syntax.const @{syntax_const "_match"} $ p $ v) $ t
   164               (Syntax.const @{syntax_const "_match"} $ p $ v) $ t
   165           end;
   165           end;
   166 
   166 
   167   in [(@{const_syntax Rep_cfun}, K Case1_tr')] end;
   167   in [(@{const_syntax Rep_cfun}, K Case1_tr')] end;
   168 *}
   168 \<close>
   169 
   169 
   170 translations
   170 translations
   171   "x" <= "_match (CONST succeed) (_variable x)"
   171   "x" <= "_match (CONST succeed) (_variable x)"
   172 
   172 
   173 
   173 
   174 subsection {* Pattern combinators for data constructors *}
   174 subsection \<open>Pattern combinators for data constructors\<close>
   175 
   175 
   176 type_synonym ('a, 'b) pat = "'a \<rightarrow> 'b match"
   176 type_synonym ('a, 'b) pat = "'a \<rightarrow> 'b match"
   177 
   177 
   178 definition
   178 definition
   179   cpair_pat :: "('a, 'c) pat \<Rightarrow> ('b, 'd) pat \<Rightarrow> ('a \<times> 'b, 'c \<times> 'd) pat" where
   179   cpair_pat :: "('a, 'c) pat \<Rightarrow> ('b, 'd) pat \<Rightarrow> ('a \<times> 'b, 'c \<times> 'd) pat" where
   207 
   207 
   208 definition
   208 definition
   209   ONE_pat :: "(one, unit) pat" where
   209   ONE_pat :: "(one, unit) pat" where
   210   "ONE_pat = (\<Lambda> ONE. succeed\<cdot>())"
   210   "ONE_pat = (\<Lambda> ONE. succeed\<cdot>())"
   211 
   211 
   212 text {* Parse translations (patterns) *}
   212 text \<open>Parse translations (patterns)\<close>
   213 translations
   213 translations
   214   "_pat (XCONST Pair x y)" => "CONST cpair_pat (_pat x) (_pat y)"
   214   "_pat (XCONST Pair x y)" => "CONST cpair_pat (_pat x) (_pat y)"
   215   "_pat (XCONST spair\<cdot>x\<cdot>y)" => "CONST spair_pat (_pat x) (_pat y)"
   215   "_pat (XCONST spair\<cdot>x\<cdot>y)" => "CONST spair_pat (_pat x) (_pat y)"
   216   "_pat (XCONST sinl\<cdot>x)" => "CONST sinl_pat (_pat x)"
   216   "_pat (XCONST sinl\<cdot>x)" => "CONST sinl_pat (_pat x)"
   217   "_pat (XCONST sinr\<cdot>x)" => "CONST sinr_pat (_pat x)"
   217   "_pat (XCONST sinr\<cdot>x)" => "CONST sinr_pat (_pat x)"
   218   "_pat (XCONST up\<cdot>x)" => "CONST up_pat (_pat x)"
   218   "_pat (XCONST up\<cdot>x)" => "CONST up_pat (_pat x)"
   219   "_pat (XCONST TT)" => "CONST TT_pat"
   219   "_pat (XCONST TT)" => "CONST TT_pat"
   220   "_pat (XCONST FF)" => "CONST FF_pat"
   220   "_pat (XCONST FF)" => "CONST FF_pat"
   221   "_pat (XCONST ONE)" => "CONST ONE_pat"
   221   "_pat (XCONST ONE)" => "CONST ONE_pat"
   222 
   222 
   223 text {* CONST version is also needed for constructors with special syntax *}
   223 text \<open>CONST version is also needed for constructors with special syntax\<close>
   224 translations
   224 translations
   225   "_pat (CONST Pair x y)" => "CONST cpair_pat (_pat x) (_pat y)"
   225   "_pat (CONST Pair x y)" => "CONST cpair_pat (_pat x) (_pat y)"
   226   "_pat (CONST spair\<cdot>x\<cdot>y)" => "CONST spair_pat (_pat x) (_pat y)"
   226   "_pat (CONST spair\<cdot>x\<cdot>y)" => "CONST spair_pat (_pat x) (_pat y)"
   227 
   227 
   228 text {* Parse translations (variables) *}
   228 text \<open>Parse translations (variables)\<close>
   229 translations
   229 translations
   230   "_variable (XCONST Pair x y) r" => "_variable (_args x y) r"
   230   "_variable (XCONST Pair x y) r" => "_variable (_args x y) r"
   231   "_variable (XCONST spair\<cdot>x\<cdot>y) r" => "_variable (_args x y) r"
   231   "_variable (XCONST spair\<cdot>x\<cdot>y) r" => "_variable (_args x y) r"
   232   "_variable (XCONST sinl\<cdot>x) r" => "_variable x r"
   232   "_variable (XCONST sinl\<cdot>x) r" => "_variable x r"
   233   "_variable (XCONST sinr\<cdot>x) r" => "_variable x r"
   233   "_variable (XCONST sinr\<cdot>x) r" => "_variable x r"
   238 
   238 
   239 translations
   239 translations
   240   "_variable (CONST Pair x y) r" => "_variable (_args x y) r"
   240   "_variable (CONST Pair x y) r" => "_variable (_args x y) r"
   241   "_variable (CONST spair\<cdot>x\<cdot>y) r" => "_variable (_args x y) r"
   241   "_variable (CONST spair\<cdot>x\<cdot>y) r" => "_variable (_args x y) r"
   242 
   242 
   243 text {* Print translations *}
   243 text \<open>Print translations\<close>
   244 translations
   244 translations
   245   "CONST Pair (_match p1 v1) (_match p2 v2)"
   245   "CONST Pair (_match p1 v1) (_match p2 v2)"
   246       <= "_match (CONST cpair_pat p1 p2) (_args v1 v2)"
   246       <= "_match (CONST cpair_pat p1 p2) (_args v1 v2)"
   247   "CONST spair\<cdot>(_match p1 v1)\<cdot>(_match p2 v2)"
   247   "CONST spair\<cdot>(_match p1 v1)\<cdot>(_match p2 v2)"
   248       <= "_match (CONST spair_pat p1 p2) (_args v1 v2)"
   248       <= "_match (CONST spair_pat p1 p2) (_args v1 v2)"
   316   "branch ONE_pat\<cdot>(unit_when\<cdot>r)\<cdot>\<bottom> = \<bottom>"
   316   "branch ONE_pat\<cdot>(unit_when\<cdot>r)\<cdot>\<bottom> = \<bottom>"
   317   "branch ONE_pat\<cdot>(unit_when\<cdot>r)\<cdot>ONE = succeed\<cdot>r"
   317   "branch ONE_pat\<cdot>(unit_when\<cdot>r)\<cdot>ONE = succeed\<cdot>r"
   318 by (simp_all add: branch_def ONE_pat_def)
   318 by (simp_all add: branch_def ONE_pat_def)
   319 
   319 
   320 
   320 
   321 subsection {* Wildcards, as-patterns, and lazy patterns *}
   321 subsection \<open>Wildcards, as-patterns, and lazy patterns\<close>
   322 
   322 
   323 definition
   323 definition
   324   wild_pat :: "'a \<rightarrow> unit match" where
   324   wild_pat :: "'a \<rightarrow> unit match" where
   325   "wild_pat = (\<Lambda> x. succeed\<cdot>())"
   325   "wild_pat = (\<Lambda> x. succeed\<cdot>())"
   326 
   326 
   330 
   330 
   331 definition
   331 definition
   332   lazy_pat :: "('a \<rightarrow> 'b::pcpo match) \<Rightarrow> ('a \<rightarrow> 'b match)" where
   332   lazy_pat :: "('a \<rightarrow> 'b::pcpo match) \<Rightarrow> ('a \<rightarrow> 'b match)" where
   333   "lazy_pat p = (\<Lambda> x. succeed\<cdot>(cases\<cdot>(p\<cdot>x)))"
   333   "lazy_pat p = (\<Lambda> x. succeed\<cdot>(cases\<cdot>(p\<cdot>x)))"
   334 
   334 
   335 text {* Parse translations (patterns) *}
   335 text \<open>Parse translations (patterns)\<close>
   336 translations
   336 translations
   337   "_pat _" => "CONST wild_pat"
   337   "_pat _" => "CONST wild_pat"
   338 
   338 
   339 text {* Parse translations (variables) *}
   339 text \<open>Parse translations (variables)\<close>
   340 translations
   340 translations
   341   "_variable _ r" => "_variable _noargs r"
   341   "_variable _ r" => "_variable _noargs r"
   342 
   342 
   343 text {* Print translations *}
   343 text \<open>Print translations\<close>
   344 translations
   344 translations
   345   "_" <= "_match (CONST wild_pat) _noargs"
   345   "_" <= "_match (CONST wild_pat) _noargs"
   346 
   346 
   347 lemma wild_pat [simp]: "branch wild_pat\<cdot>(unit_when\<cdot>r)\<cdot>x = succeed\<cdot>r"
   347 lemma wild_pat [simp]: "branch wild_pat\<cdot>(unit_when\<cdot>r)\<cdot>x = succeed\<cdot>r"
   348 by (simp add: branch_def wild_pat_def)
   348 by (simp add: branch_def wild_pat_def)
   359   "branch p\<cdot>r\<cdot>x = succeed\<cdot>s \<Longrightarrow> branch (lazy_pat p)\<cdot>r\<cdot>x = succeed\<cdot>s"
   359   "branch p\<cdot>r\<cdot>x = succeed\<cdot>s \<Longrightarrow> branch (lazy_pat p)\<cdot>r\<cdot>x = succeed\<cdot>s"
   360 apply (simp_all add: branch_def lazy_pat_def)
   360 apply (simp_all add: branch_def lazy_pat_def)
   361 apply (cases "p\<cdot>x", simp_all)+
   361 apply (cases "p\<cdot>x", simp_all)+
   362 done
   362 done
   363 
   363 
   364 subsection {* Examples *}
   364 subsection \<open>Examples\<close>
   365 
   365 
   366 term "Case t of (:up\<cdot>(sinl\<cdot>x), sinr\<cdot>y:) \<Rightarrow> (x, y)"
   366 term "Case t of (:up\<cdot>(sinl\<cdot>x), sinr\<cdot>y:) \<Rightarrow> (x, y)"
   367 
   367 
   368 term "\<Lambda> t. Case t of up\<cdot>(sinl\<cdot>a) \<Rightarrow> a | up\<cdot>(sinr\<cdot>b) \<Rightarrow> b"
   368 term "\<Lambda> t. Case t of up\<cdot>(sinl\<cdot>a) \<Rightarrow> a | up\<cdot>(sinr\<cdot>b) \<Rightarrow> b"
   369 
   369 
   370 term "\<Lambda> t. Case t of (:up\<cdot>(sinl\<cdot>_), sinr\<cdot>x:) \<Rightarrow> x"
   370 term "\<Lambda> t. Case t of (:up\<cdot>(sinl\<cdot>_), sinr\<cdot>x:) \<Rightarrow> x"
   371 
   371 
   372 subsection {* ML code for generating definitions *}
   372 subsection \<open>ML code for generating definitions\<close>
   373 
   373 
   374 ML {*
   374 ML \<open>
   375 local open HOLCF_Library in
   375 local open HOLCF_Library in
   376 
   376 
   377 infixr 6 ->>;
   377 infixr 6 ->>;
   378 infix 9 ` ;
   378 infix 9 ` ;
   379 
   379 
   584   in
   584   in
   585     (pat_stricts @ pat_apps, thy)
   585     (pat_stricts @ pat_apps, thy)
   586   end
   586   end
   587 
   587 
   588 end
   588 end
   589 *}
   589 \<close>
   590 
   590 
   591 (*
   591 (*
   592 Cut from HOLCF/Tools/domain_constructors.ML
   592 Cut from HOLCF/Tools/domain_constructors.ML
   593 in function add_domain_constructors:
   593 in function add_domain_constructors:
   594 
   594