src/HOL/Library/Pattern_Aliases.thy
author Lars Hupel <lars.hupel@mytum.de>
Fri, 18 Aug 2017 14:57:23 +0200
changeset 66451 5be0b0604d71
child 66481 d35f7a9f92e2
permissions -rw-r--r--
syntax for pattern aliases
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     1
(*  Title:      HOL/Library/Pattern_Aliases.thy
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     2
    Author:     Lars Hupel, Ondrej Kuncar
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     3
*)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     4
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     5
section \<open>Input syntax for pattern aliases (or ``as-patterns'' in Haskell)\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     6
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     7
theory Pattern_Aliases
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     8
imports Main
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
     9
begin
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    10
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    11
text \<open>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    12
  Most functional languages (Haskell, ML, Scala) support aliases in patterns. This allows to refer
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    13
  to a subpattern with a variable name. This theory implements this using a check phase. It works
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    14
  well for function definitions (see usage below).
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    15
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    16
  The following caveats should be kept in mind:
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    17
  \<^item> The translation expects a term of the form @{prop "f x y = rhs"}, where \<open>x\<close> and \<open>y\<close> are patterns
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    18
    that may contain aliases. The result of the translation is a nested @{const Let}-expression on
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    19
    the right hand side. The code generator \<^emph>\<open>does not\<close> print Isabelle pattern aliases to target
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    20
    language pattern aliases.
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    21
  \<^item> The translation does not process nested equalities; only the top-level equality is translated.
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    22
  \<^item> Terms that do not adhere to the above shape may either stay untranslated or produce an error
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    23
    message. The @{command fun} command will complain if pattern aliases are left untranslated.
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    24
    In particular, there are no checks whether the patterns are wellformed or linear.
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    25
  \<^item> There is no corresonding uncheck phase, because it is unclear in which situations the
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    26
    translation should be reversed.
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    27
\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    28
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    29
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    30
subsection \<open>Definition\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    31
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    32
consts as :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    33
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    34
ML\<open>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    35
local
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    36
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    37
fun let_typ a b = a --> (a --> b) --> b
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    38
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    39
fun strip_all t =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    40
  case try Logic.dest_all t of
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    41
    NONE => ([], t)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    42
  | SOME (var, t) => apfst (cons var) (strip_all t)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    43
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    44
fun all_Frees t =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    45
  fold_aterms (fn Free (x, t) => insert op = (x, t) | _ => I) t []
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    46
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    47
in
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    48
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    49
fun check_pattern_syntax t =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    50
  case strip_all t of
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    51
    (vars, @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ lhs $ rhs)) =>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    52
      let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    53
        fun go (Const (@{const_name as}, _) $ pat $ var, rhs) =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    54
              let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    55
                val (pat', rhs') = go (pat, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    56
                val _ = if is_Free var then () else error "Left-hand side of =: must be a free variable"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    57
                val rhs'' =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    58
                  Const (@{const_name Let}, let_typ (fastype_of var) (fastype_of rhs)) $
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    59
                    pat' $ lambda var rhs'
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    60
              in
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    61
                (pat', rhs'')
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    62
              end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    63
          | go (t $ u, rhs) =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    64
              let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    65
                val (t', rhs') = go (t, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    66
                val (u', rhs'') = go (u, rhs')
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    67
              in (t' $ u', rhs'') end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    68
          | go (t, rhs) = (t, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    69
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    70
        val (lhs', rhs') = go (lhs, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    71
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    72
        val res = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs', rhs'))
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    73
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    74
        val frees = filter (member op = vars) (all_Frees res)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    75
      in fold (fn v => Logic.dependent_all_name ("", v)) (map Free frees) res end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    76
  | _ => t
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    77
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    78
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    79
\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    80
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    81
bundle pattern_aliases begin
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    82
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    83
  notation as (infixr "=:" 1)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    84
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    85
  declaration \<open>K (Syntax_Phases.term_check 98 "pattern_syntax" (K (map check_pattern_syntax)))\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    86
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    87
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    88
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    89
hide_const (open) as
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    90
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    91
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    92
subsection \<open>Usage\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    93
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    94
context includes pattern_aliases begin
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    95
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    96
text \<open>Not very useful for plain definitions, but works anyway.\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    97
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    98
private definition "test_1 x (y =: z) = y + z"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    99
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   100
lemma "test_1 x y = y + y"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   101
by (rule test_1_def[unfolded Let_def])
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   102
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   103
text \<open>Very useful for function definitions.\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   104
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   105
private fun test_2 where
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   106
"test_2 (y # (y' # ys =: x') =: x) = x @ x'" |
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   107
"test_2 _ = []"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   108
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   109
lemma "test_2 (y # y' # ys) = (y # y' # ys) @ y' # ys"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   110
by (rule test_2.simps[unfolded Let_def])
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   111
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   112
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   113
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   114
end