src/HOL/Library/Pattern_Aliases.thy
author wenzelm
Sat, 02 Jun 2018 22:14:35 +0200
changeset 68356 46d5a9f428e1
parent 67405 e9ab4ad7bd15
child 69593 3dda49e08b9d
permissions -rw-r--r--
more formal comments;
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
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
     2
    Author:     Lars Hupel, Ondrej Kuncar, Tobias Nipkow
66451
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
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    14
  well for function definitions (see usage below). All features are packed into a @{command bundle}.
66451
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.
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    25
  \<^item> The corresponding uncheck phase attempts to reverse the translation (no guarantee). The
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    26
    additionally introduced variables are bound using a ``fake quantifier'' that does not
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    27
    appear in the output.
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    28
  \<^item> To obtain reasonable induction principles in function definitions, the bundle also declares
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    29
    a custom congruence rule for @{const Let} that only affects @{command fun}. This congruence
66485
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    30
    rule might lead to an explosion in term size (although that is rare)! In some circumstances
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    31
    (using \<open>let\<close> to destructure tuples), the internal construction of functions stumbles over this
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    32
    rule and prints an error. To mitigate this, either
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    33
    \<^item> activate the bundle locally (@{theory_text \<open>context includes ... begin\<close>}) or
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    34
    \<^item> rewrite the \<open>let\<close>-expression to use \<open>case\<close>: @{term \<open>let (a, b) = x in (b, a)\<close>} becomes
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    35
      @{term \<open>case x of (a, b) \<Rightarrow> (b, a)\<close>}.
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
    36
  \<^item> The bundle also adds the @{thm Let_def} rule to the simpset.
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    37
\<close>
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
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    40
subsection \<open>Definition\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    41
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    42
consts
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    43
  as :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    44
  fake_quant :: "('a \<Rightarrow> prop) \<Rightarrow> prop"
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    45
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    46
lemma let_cong_unfolding: "M = N \<Longrightarrow> f N = g N \<Longrightarrow> Let M f = Let N g"
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    47
by simp
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    48
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    49
translations "P" <= "CONST fake_quant (\<lambda>x. P)"
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    50
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    51
ML\<open>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    52
local
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    53
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    54
fun let_typ a b = a --> (a --> b) --> b
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    55
fun as_typ a = a --> a --> a
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    56
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    57
fun strip_all t =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    58
  case try Logic.dest_all t of
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    59
    NONE => ([], t)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    60
  | SOME (var, t) => apfst (cons var) (strip_all t)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    61
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    62
fun all_Frees t =
67405
e9ab4ad7bd15 uniform use of Standard ML op-infix -- eliminated warnings;
wenzelm
parents: 67399
diff changeset
    63
  fold_aterms (fn Free (x, t) => insert (op =) (x, t) | _ => I) t []
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    64
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    65
fun subst_once (old, new) t =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    66
  let
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    67
    fun go t =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    68
      if t = old then
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    69
        (new, true)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    70
      else
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    71
        case t of
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    72
          u $ v =>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    73
            let
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    74
              val (u', substituted) = go u
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    75
            in
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    76
              if substituted then
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    77
                (u' $ v, true)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    78
              else
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    79
                case go v of (v', substituted) => (u $ v', substituted)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    80
            end
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    81
        | Abs (name, typ, t) =>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    82
            (case go t of (t', substituted) => (Abs (name, typ, t'), substituted))
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    83
        | _ => (t, false)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    84
  in fst (go t) end
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
    85
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    86
(* adapted from logic.ML *)
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    87
fun fake_const T = Const (@{const_name fake_quant}, (T --> propT) --> propT);
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    88
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    89
fun dependent_fake_name v t =
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    90
  let
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    91
    val x = Term.term_name v
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    92
    val T = Term.fastype_of v
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    93
    val t' = Term.abstract_over (v, t)
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    94
  in if Term.is_dependent t' then fake_const T $ Abs (x, T, t') else t end
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
    95
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    96
in
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
fun check_pattern_syntax t =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
    99
  case strip_all t of
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   100
    (vars, @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ lhs $ rhs)) =>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   101
      let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   102
        fun go (Const (@{const_name as}, _) $ pat $ var, rhs) =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   103
              let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   104
                val (pat', rhs') = go (pat, rhs)
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   105
                val _ = if is_Free var then () else error "Right-hand side of =: must be a free variable"
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   106
                val rhs'' =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   107
                  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
   108
                    pat' $ lambda var rhs'
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   109
              in
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   110
                (pat', rhs'')
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   111
              end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   112
          | go (t $ u, rhs) =
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   113
              let
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   114
                val (t', rhs') = go (t, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   115
                val (u', rhs'') = go (u, rhs')
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   116
              in (t' $ u', rhs'') end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   117
          | go (t, rhs) = (t, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   118
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   119
        val (lhs', rhs') = go (lhs, rhs)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   120
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   121
        val res = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs', rhs'))
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   122
67405
e9ab4ad7bd15 uniform use of Standard ML op-infix -- eliminated warnings;
wenzelm
parents: 67399
diff changeset
   123
        val frees = filter (member (op =) vars) (all_Frees res)
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   124
      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
   125
  | _ => t
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   126
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   127
fun uncheck_pattern_syntax ctxt t =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   128
  case strip_all t of
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   129
    (vars, @{const Trueprop} $ (Const (@{const_name HOL.eq}, _) $ lhs $ rhs)) =>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   130
      let
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   131
        (* restricted to going down abstractions; ignores eta-contracted rhs *)
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   132
        fun go lhs (rhs as Const (@{const_name Let}, _) $ pat $ Abs (name, typ, t)) ctxt frees =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   133
              if exists_subterm (fn t' => t' = pat) lhs then
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   134
                let
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   135
                  val ([name'], ctxt') = Variable.variant_fixes [name] ctxt
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   136
                  val free = Free (name', typ)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   137
                  val subst = (pat, Const (@{const_name as}, as_typ typ) $ pat $ free)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   138
                  val lhs' = subst_once subst lhs
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   139
                  val rhs' = subst_bound (free, t)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   140
                in
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   141
                  go lhs' rhs' ctxt' (Free (name', typ) :: frees)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   142
                end
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   143
              else
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   144
                (lhs, rhs, ctxt, frees)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   145
          | go lhs rhs ctxt frees = (lhs, rhs, ctxt, frees)
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   146
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   147
        val (lhs', rhs', _, frees) = go lhs rhs ctxt []
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   148
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   149
        val res =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   150
          HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs', rhs'))
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   151
          |> fold (fn v => Logic.dependent_all_name ("", v)) (map Free vars)
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   152
          |> fold dependent_fake_name frees
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   153
      in
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   154
        if null frees then t else res
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   155
      end
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   156
  | _ => t
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   157
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   158
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   159
\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   160
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   161
bundle pattern_aliases begin
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   162
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   163
  notation as (infixr "=:" 1)
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   164
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   165
  declaration \<open>K (Syntax_Phases.term_check 98 "pattern_syntax" (K (map check_pattern_syntax)))\<close>
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   166
  declaration \<open>K (Syntax_Phases.term_uncheck 98 "pattern_syntax" (map o uncheck_pattern_syntax))\<close>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   167
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   168
  declare let_cong_unfolding [fundef_cong]
66485
Lars Hupel <lars.hupel@mytum.de>
parents: 66483
diff changeset
   169
  declare Let_def [simp]
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   170
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   171
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   172
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   173
hide_const as
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   174
hide_const fake_quant
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   175
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   176
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   177
subsection \<open>Usage\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   178
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   179
context includes pattern_aliases begin
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   180
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   181
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
   182
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   183
private definition "test_1 x (y =: z) = y + z"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   184
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   185
lemma "test_1 x y = y + y"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   186
by (rule test_1_def[unfolded Let_def])
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   187
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   188
text \<open>Very useful for function definitions.\<close>
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   189
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   190
private fun test_2 where
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   191
"test_2 (y # (y' # ys =: x') =: x) = x @ x' @ x'" |
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   192
"test_2 _ = []"
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   193
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   194
lemma "test_2 (y # y' # ys) = (y # y' # ys) @ (y' # ys) @ (y' # ys)"
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   195
by (rule test_2.simps[unfolded Let_def])
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   196
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   197
ML\<open>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   198
let
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   199
  val actual =
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   200
    @{thm test_2.simps(1)}
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   201
    |> Thm.prop_of
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   202
    |> Syntax.string_of_term @{context}
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   203
    |> YXML.content_of
66483
123acfd5fe35 tuned syntax
Lars Hupel <lars.hupel@mytum.de>
parents: 66481
diff changeset
   204
  val expected = "test_2 (?y # (?y' # ?ys =: x') =: x) = x @ x' @ x'"
66481
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   205
in @{assert} (actual = expected) end
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   206
\<close>
d35f7a9f92e2 output syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents: 66451
diff changeset
   207
66451
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   208
end
5be0b0604d71 syntax for pattern aliases
Lars Hupel <lars.hupel@mytum.de>
parents:
diff changeset
   209
67399
eab6ce8368fa ran isabelle update_op on all sources
nipkow
parents: 66485
diff changeset
   210
end