75 lines
2.0 KiB
Plaintext
75 lines
2.0 KiB
Plaintext
(*
|
|
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*)
|
|
|
|
theory TermPatternAntiquote_Tests
|
|
imports
|
|
Lib.TermPatternAntiquote
|
|
Main
|
|
begin
|
|
|
|
text \<open>
|
|
Term pattern matching utility.
|
|
|
|
Instead of writing monstrosities such as
|
|
|
|
@{verbatim \<open>
|
|
case t of
|
|
Const ("Pure.imp", _) $
|
|
P $
|
|
Const (@{const_name Trueprop}, _) $
|
|
(Const ("HOL.eq", _) $
|
|
(Const (@{const_name "my_func"}, _) $ x) $ y)
|
|
=> (P, x, y)
|
|
\<close>}
|
|
|
|
simply use a term pattern with variables:
|
|
|
|
@{verbatim \<open>
|
|
case t of
|
|
@{term_pat "PROP ?P \<Longrightarrow> my_func ?x = ?y"} => (P, x, y)
|
|
\<close>}
|
|
|
|
Each term_pat generates an ML pattern that can be used in any
|
|
case-expression or name binding.
|
|
The ML pattern matches directly on the term datatype; it does not
|
|
perform matching in the Isabelle logic.
|
|
|
|
Schematic variables in the pattern generate ML variables.
|
|
The variables must obey ML's pattern matching rules, i.e.
|
|
each can appear only once.
|
|
|
|
Due to the difficulty of enforcing this rule for type variables,
|
|
schematic type variables are ignored and not checked.
|
|
\<close>
|
|
|
|
text \<open>
|
|
Example: evaluate arithmetic expressions in ML.
|
|
\<close>
|
|
ML_val \<open>
|
|
fun eval_num @{term_pat "numeral ?n"} = HOLogic.dest_numeral n
|
|
| eval_num @{term_pat "Suc ?n"} = eval_num n + 1
|
|
| eval_num @{term_pat "0"} = 0
|
|
| eval_num @{term_pat "1"} = 1
|
|
| eval_num @{term_pat "?x + ?y"} = eval_num x + eval_num y
|
|
| eval_num @{term_pat "?x - ?y"} = eval_num x - eval_num y
|
|
| eval_num @{term_pat "?x * ?y"} = eval_num x * eval_num y
|
|
| eval_num @{term_pat "?x div ?y"} = eval_num x div eval_num y
|
|
| eval_num t = raise TERM ("eval_num", [t]);
|
|
|
|
eval_num @{term "(1 + 2) * 3 - 4 div 5"}
|
|
\<close>
|
|
|
|
text \<open>Regression test: backslash handling\<close>
|
|
ML_val \<open>
|
|
val @{term_pat "\<alpha>"} = @{term "\<alpha>"}
|
|
\<close>
|
|
|
|
text \<open>Regression test: special-casing for dummy vars\<close>
|
|
ML_val \<open>
|
|
val @{term_pat "\<lambda>x y. _"} = @{term "\<lambda>x y. z"}
|
|
\<close>
|
|
|
|
end |