author | wenzelm |
Sun, 15 Mar 2020 11:55:16 +0100 | |
changeset 71555 | 7eadccd4392c |
parent 69597 | ff784d5a5bfb |
child 75160 | d48998648281 |
permissions | -rw-r--r-- |
61656 | 1 |
(*:maxLineLen=78:*) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
2 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
3 |
theory Manual |
66453
cc19f7ca2ed6
session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
wenzelm
parents:
62969
diff
changeset
|
4 |
imports Base "HOL-Eisbach.Eisbach_Tools" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
5 |
begin |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
6 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
7 |
chapter \<open>The method command\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
8 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
9 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
10 |
The @{command_def method} command provides the ability to write proof |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
11 |
methods by combining existing ones with their usual syntax. Specifically it |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
12 |
allows compound proof methods to be named, and to extend the name space of |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
13 |
basic methods accordingly. Method definitions may abstract over parameters: |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
14 |
terms, facts, or other methods. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
15 |
|
61417 | 16 |
\<^medskip> |
61576 | 17 |
The syntax diagram below refers to some syntactic categories that are |
18 |
further defined in @{cite "isabelle-isar-ref"}. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
19 |
|
69597 | 20 |
\<^rail>\<open> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
21 |
@@{command method} name args @'=' method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
22 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
23 |
args: term_args? method_args? \<newline> fact_args? decl_args? |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
24 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
25 |
term_args: @'for' @{syntax "fixes"} |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
26 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
27 |
method_args: @'methods' (name+) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
28 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
29 |
fact_args: @'uses' (name+) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
30 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
31 |
decl_args: @'declares' (name+) |
69597 | 32 |
\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
33 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
34 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
35 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
36 |
section \<open>Basic method definitions\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
37 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
38 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
39 |
Consider the following proof that makes use of usual Isar method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
40 |
combinators. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
41 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
42 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
43 |
lemma "P \<and> Q \<longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
44 |
by ((rule impI, (erule conjE)?) | assumption)+ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
45 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
46 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
47 |
It is clear that this compound method will be applicable in more cases than |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
48 |
this proof alone. With the @{command method} command we can define a proof |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
49 |
method that makes the above functionality available generally. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
50 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
51 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
52 |
method prop_solver\<^sub>1 = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
53 |
((rule impI, (erule conjE)?) | assumption)+ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
54 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
55 |
lemma "P \<and> Q \<and> R \<longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
56 |
by prop_solver\<^sub>1 |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
57 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
58 |
text \<open> |
61576 | 59 |
In this example, the facts \<open>impI\<close> and \<open>conjE\<close> are static. They are evaluated |
60 |
once when the method is defined and cannot be changed later. This makes the |
|
61 |
method stable in the sense of \<^emph>\<open>static scoping\<close>: naming another fact \<open>impI\<close> |
|
62 |
in a later context won't affect the behaviour of \<open>prop_solver\<^sub>1\<close>. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
63 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
64 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
65 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
66 |
section \<open>Term abstraction\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
67 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
68 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
69 |
Methods can also abstract over terms using the @{keyword_def "for"} keyword, |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
70 |
optionally providing type constraints. For instance, the following proof |
69597 | 71 |
method \<open>intro_ex\<close> takes a term \<^term>\<open>y\<close> of any type, which it uses to |
72 |
instantiate the \<^term>\<open>x\<close>-variable of \<open>exI\<close> (existential introduction) |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
73 |
before applying the result as a rule. The instantiation is performed here by |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
74 |
Isar's @{attribute_ref "where"} attribute. If the current subgoal is to find |
69597 | 75 |
a witness for the given predicate \<^term>\<open>Q\<close>, then this has the effect of |
76 |
committing to \<^term>\<open>y\<close>. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
77 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
78 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
79 |
method intro_ex for Q :: "'a \<Rightarrow> bool" and y :: 'a = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
80 |
(rule exI ["where" P = Q and x = y]) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
81 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
82 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
83 |
text \<open> |
69597 | 84 |
The term parameters \<^term>\<open>y\<close> and \<^term>\<open>Q\<close> can be used arbitrarily inside |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
85 |
the method body, as part of attribute applications or arguments to other |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
86 |
methods. The expression is type-checked as far as possible when the method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
87 |
is defined, however dynamic type errors can still occur when it is invoked |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
88 |
(e.g.\ when terms are instantiated in a parameterized fact). Actual term |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
89 |
arguments are supplied positionally, in the same order as in the method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
90 |
definition. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
91 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
92 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
93 |
lemma "P a \<Longrightarrow> \<exists>x. P x" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
94 |
by (intro_ex P a) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
95 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
96 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
97 |
section \<open>Fact abstraction\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
98 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
99 |
subsection \<open>Named theorems\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
100 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
101 |
text \<open> |
61576 | 102 |
A \<^emph>\<open>named theorem\<close> is a fact whose contents are produced dynamically within |
103 |
the current proof context. The Isar command @{command_ref "named_theorems"} |
|
104 |
provides simple access to this concept: it declares a dynamic fact with |
|
105 |
corresponding \<^emph>\<open>attribute\<close> for managing this particular data slot in the |
|
106 |
context. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
107 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
108 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
109 |
named_theorems intros |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
110 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
111 |
text \<open> |
61493 | 112 |
So far \<open>intros\<close> refers to the empty fact. Using the Isar command |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
113 |
@{command_ref "declare"} we may apply declaration attributes to the context. |
61576 | 114 |
Below we declare both \<open>conjI\<close> and \<open>impI\<close> as \<open>intros\<close>, adding them to the |
115 |
named theorem slot. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
116 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
117 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
118 |
declare conjI [intros] and impI [intros] |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
119 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
120 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
121 |
We can refer to named theorems as dynamic facts within a particular proof |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
122 |
context, which are evaluated whenever the method is invoked. Instead of |
61493 | 123 |
having facts hard-coded into the method, as in \<open>prop_solver\<^sub>1\<close>, we can |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
124 |
instead refer to these named theorems. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
125 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
126 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
127 |
named_theorems elims |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
128 |
declare conjE [elims] |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
129 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
130 |
method prop_solver\<^sub>3 = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
131 |
((rule intros, (erule elims)?) | assumption)+ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
132 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
133 |
lemma "P \<and> Q \<longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
134 |
by prop_solver\<^sub>3 |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
135 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
136 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
137 |
Often these named theorems need to be augmented on the spot, when a method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
138 |
is invoked. The @{keyword_def "declares"} keyword in the signature of |
61576 | 139 |
@{command method} adds the common method syntax \<open>method decl: facts\<close> for |
140 |
each named theorem \<open>decl\<close>. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
141 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
142 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
143 |
method prop_solver\<^sub>4 declares intros elims = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
144 |
((rule intros, (erule elims)?) | assumption)+ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
145 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
146 |
lemma "P \<and> (P \<longrightarrow> Q) \<longrightarrow> Q \<and> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
147 |
by (prop_solver\<^sub>4 elims: impE intros: conjI) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
148 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
149 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
150 |
subsection \<open>Simple fact abstraction\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
151 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
152 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
153 |
The @{keyword "declares"} keyword requires that a corresponding dynamic fact |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
154 |
has been declared with @{command_ref named_theorems}. This is useful for |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
155 |
managing collections of facts which are to be augmented with declarations, |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
156 |
but is overkill if we simply want to pass a fact to a method. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
157 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
158 |
We may use the @{keyword_def "uses"} keyword in the method header to provide |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
159 |
a simple fact parameter. In contrast to @{keyword "declares"}, these facts |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
160 |
are always implicitly empty unless augmented when the method is invoked. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
161 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
162 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
163 |
method rule_twice uses my_rule = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
164 |
(rule my_rule, rule my_rule) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
165 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
166 |
lemma "P \<Longrightarrow> Q \<Longrightarrow> (P \<and> Q) \<and> Q" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
167 |
by (rule_twice my_rule: conjI) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
168 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
169 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
170 |
section \<open>Higher-order methods\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
171 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
172 |
text \<open> |
61576 | 173 |
The \<^emph>\<open>structured concatenation\<close> combinator ``\<open>method\<^sub>1 ; method\<^sub>2\<close>'' was |
174 |
introduced in Isabelle2015, motivated by development of Eisbach. It is |
|
175 |
similar to ``\<open>method\<^sub>1, method\<^sub>2\<close>'', but \<open>method\<^sub>2\<close> is invoked on on \<^emph>\<open>all\<close> |
|
176 |
subgoals that have newly emerged from \<open>method\<^sub>1\<close>. This is useful to handle |
|
177 |
cases where the number of subgoals produced by a method is determined |
|
178 |
dynamically at run-time. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
179 |
\<close> |
61417 | 180 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
181 |
method conj_with uses rule = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
182 |
(intro conjI ; intro rule) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
183 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
184 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
185 |
assumes A: "P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
186 |
shows "P \<and> P \<and> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
187 |
by (conj_with rule: A) |
61417 | 188 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
189 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
190 |
Method definitions may take other methods as arguments, and thus implement |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
191 |
method combinators with prefix syntax. For example, to more usefully exploit |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
192 |
Isabelle's backtracking, the explicit requirement that a method solve all |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
193 |
produced subgoals is frequently useful. This can easily be written as a |
61576 | 194 |
\<^emph>\<open>higher-order method\<close> using ``\<open>;\<close>''. The @{keyword "methods"} keyword |
195 |
denotes method parameters that are other proof methods to be invoked by the |
|
196 |
method being defined. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
197 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
198 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
199 |
method solve methods m = (m ; fail) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
200 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
201 |
text \<open> |
61576 | 202 |
Given some method-argument \<open>m\<close>, \<open>solve \<open>m\<close>\<close> applies the method \<open>m\<close> and then |
203 |
fails whenever \<open>m\<close> produces any new unsolved subgoals --- i.e. when \<open>m\<close> |
|
204 |
fails to completely discharge the goal it was applied to. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
205 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
206 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
207 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
208 |
section \<open>Example\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
209 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
210 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
211 |
With these simple features we are ready to write our first non-trivial proof |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
212 |
method. Returning to the first-order logic example, the following method |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
213 |
definition applies various rules with their canonical methods. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
214 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
215 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
216 |
named_theorems subst |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
217 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
218 |
method prop_solver declares intros elims subst = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
219 |
(assumption | |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
220 |
(rule intros) | erule elims | |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
221 |
subst subst | subst (asm) subst | |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
222 |
(erule notE ; solve \<open>prop_solver\<close>))+ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
223 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
224 |
text \<open> |
61576 | 225 |
The only non-trivial part above is the final alternative \<open>(erule notE ; |
226 |
solve \<open>prop_solver\<close>)\<close>. Here, in the case that all other alternatives fail, |
|
69597 | 227 |
the method takes one of the assumptions \<^term>\<open>\<not> P\<close> of the current goal |
61576 | 228 |
and eliminates it with the rule \<open>notE\<close>, causing the goal to be proved to |
69597 | 229 |
become \<^term>\<open>P\<close>. The method then recursively invokes itself on the |
61576 | 230 |
remaining goals. The job of the recursive call is to demonstrate that there |
69597 | 231 |
is a contradiction in the original assumptions (i.e.\ that \<^term>\<open>P\<close> can be |
61576 | 232 |
derived from them). Note this recursive invocation is applied with the |
233 |
@{method solve} method combinator to ensure that a contradiction will indeed |
|
234 |
be shown. In the case where a contradiction cannot be found, backtracking |
|
69597 | 235 |
will occur and a different assumption \<^term>\<open>\<not> Q\<close> will be chosen for |
61576 | 236 |
elimination. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
237 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
238 |
Note that the recursive call to @{method prop_solver} does not have any |
61576 | 239 |
parameters passed to it. Recall that fact parameters, e.g.\ \<open>intros\<close>, |
240 |
\<open>elims\<close>, and \<open>subst\<close>, are managed by declarations in the current proof |
|
241 |
context. They will therefore be passed to any recursive call to @{method |
|
242 |
prop_solver} and, more generally, any invocation of a method which declares |
|
243 |
these named theorems. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
244 |
|
61417 | 245 |
\<^medskip> |
246 |
After declaring some standard rules to the context, the @{method |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
247 |
prop_solver} becomes capable of solving non-trivial propositional |
61576 | 248 |
tautologies. |
249 |
\<close> |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
250 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
251 |
lemmas [intros] = |
67443
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
252 |
conjI \<comment> \<open>@{thm conjI}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
253 |
impI \<comment> \<open>@{thm impI}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
254 |
disjCI \<comment> \<open>@{thm disjCI}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
255 |
iffI \<comment> \<open>@{thm iffI}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
256 |
notI \<comment> \<open>@{thm notI}\<close> |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
257 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
258 |
lemmas [elims] = |
67443
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
259 |
impCE \<comment> \<open>@{thm impCE}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
260 |
conjE \<comment> \<open>@{thm conjE}\<close> |
3abf6a722518
standardized towards new-style formal comments: isabelle update_comments;
wenzelm
parents:
66453
diff
changeset
|
261 |
disjE \<comment> \<open>@{thm disjE}\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
262 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
263 |
lemma "(A \<or> B) \<and> (A \<longrightarrow> C) \<and> (B \<longrightarrow> C) \<longrightarrow> C" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
264 |
by prop_solver |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
265 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
266 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
267 |
chapter \<open>The match method \label{s:matching}\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
268 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
269 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
270 |
So far we have seen methods defined as simple combinations of other methods. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
271 |
Some familiar programming language concepts have been introduced (i.e.\ |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
272 |
abstraction and recursion). The only control flow has been implicitly the |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
273 |
result of backtracking. When designing more sophisticated proof methods this |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
274 |
proves too restrictive and difficult to manage conceptually. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
275 |
|
61576 | 276 |
To address this, we introduce the @{method_def match} method, which provides |
277 |
more direct access to the higher-order matching facility at the core of |
|
278 |
Isabelle. It is implemented as a separate proof method (in Isabelle/ML), and |
|
279 |
thus can be directly applied to proofs, however it is most useful when |
|
280 |
applied in the context of writing Eisbach method definitions. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
281 |
|
61417 | 282 |
\<^medskip> |
61576 | 283 |
The syntax diagram below refers to some syntactic categories that are |
284 |
further defined in @{cite "isabelle-isar-ref"}. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
285 |
|
69597 | 286 |
\<^rail>\<open> |
61912
ad710de5c576
more standard nesting of sub-language: Parse.text allows atomic entities without quotes;
wenzelm
parents:
61853
diff
changeset
|
287 |
@@{method match} kind @'in' (pattern '\<Rightarrow>' @{syntax text} + '\<bar>') |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
288 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
289 |
kind: |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
290 |
(@'conclusion' | @'premises' ('(' 'local' ')')? | |
62969 | 291 |
'(' term ')' | @{syntax thms}) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
292 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
293 |
pattern: fact_name? term args? \<newline> (@'for' fixes)? |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
294 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
295 |
fact_name: @{syntax name} @{syntax attributes}? ':' |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
296 |
; |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
297 |
args: '(' (('multi' | 'cut' nat?) + ',') ')' |
69597 | 298 |
\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
299 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
300 |
Matching allows methods to introspect the goal state, and to implement more |
61576 | 301 |
explicit control flow. In the basic case, a term or fact \<open>ts\<close> is given to |
302 |
match against as a \<^emph>\<open>match target\<close>, along with a collection of |
|
303 |
pattern-method pairs \<open>(p, m)\<close>: roughly speaking, when the pattern \<open>p\<close> |
|
304 |
matches any member of \<open>ts\<close>, the \<^emph>\<open>inner\<close> method \<open>m\<close> will be executed. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
305 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
306 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
307 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
308 |
assumes X: |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
309 |
"Q \<longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
310 |
"Q" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
311 |
shows P |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
312 |
by (match X in I: "Q \<longrightarrow> P" and I': "Q" \<Rightarrow> \<open>insert mp [OF I I']\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
313 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
314 |
text \<open> |
61576 | 315 |
In this example we have a structured Isar proof, with the named assumption |
69597 | 316 |
\<open>X\<close> and a conclusion \<^term>\<open>P\<close>. With the match method we can find the |
317 |
local facts \<^term>\<open>Q \<longrightarrow> P\<close> and \<^term>\<open>Q\<close>, binding them to separately as |
|
61576 | 318 |
\<open>I\<close> and \<open>I'\<close>. We then specialize the modus-ponens rule @{thm mp [of Q P]} to |
319 |
these facts to solve the goal. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
320 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
321 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
322 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
323 |
section \<open>Subgoal focus\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
324 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
325 |
text\<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
326 |
In the previous example we were able to match against an assumption out of |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
327 |
the Isar proof state. In general, however, proof subgoals can be |
61477 | 328 |
\<^emph>\<open>unstructured\<close>, with goal parameters and premises arising from rule |
61576 | 329 |
application. To address this, @{method match} uses \<^emph>\<open>subgoal focusing\<close> to |
330 |
produce structured goals out of unstructured ones. In place of fact or term, |
|
331 |
we may give the keyword @{keyword_def "premises"} as the match target. This |
|
332 |
causes a subgoal focus on the first subgoal, lifting local goal parameters |
|
333 |
to fixed term variables and premises into hypothetical theorems. The match |
|
334 |
is performed against these theorems, naming them and binding them as |
|
335 |
appropriate. Similarly giving the keyword @{keyword_def "conclusion"} |
|
336 |
matches against the conclusion of the first subgoal. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
337 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
338 |
An unstructured version of the previous example can then be similarly solved |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
339 |
through focusing. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
340 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
341 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
342 |
lemma "Q \<longrightarrow> P \<Longrightarrow> Q \<Longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
343 |
by (match premises in |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
344 |
I: "Q \<longrightarrow> P" and I': "Q" \<Rightarrow> \<open>insert mp [OF I I']\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
345 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
346 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
347 |
Match variables may be specified by giving a list of @{keyword_ref |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
348 |
"for"}-fixes after the pattern description. This marks those terms as bound |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
349 |
variables, which may be used in the method body. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
350 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
351 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
352 |
lemma "Q \<longrightarrow> P \<Longrightarrow> Q \<Longrightarrow> P" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
353 |
by (match premises in I: "Q \<longrightarrow> A" and I': "Q" for A \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
354 |
\<open>match conclusion in A \<Rightarrow> \<open>insert mp [OF I I']\<close>\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
355 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
356 |
text \<open> |
69597 | 357 |
In this example \<^term>\<open>A\<close> is a match variable which is bound to \<^term>\<open>P\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
358 |
upon a successful match. The inner @{method match} then matches the |
69597 | 359 |
now-bound \<^term>\<open>A\<close> (bound to \<^term>\<open>P\<close>) against the conclusion (also \<^term>\<open>P\<close>), finally applying the specialized rule to solve the goal. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
360 |
|
61576 | 361 |
Schematic terms like \<open>?P\<close> may also be used to specify match variables, but |
362 |
the result of the match is not bound, and thus cannot be used in the inner |
|
363 |
method body. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
364 |
|
61417 | 365 |
\<^medskip> |
61576 | 366 |
In the following example we extract the predicate of an existentially |
367 |
quantified conclusion in the current subgoal and search the current premises |
|
368 |
for a matching fact. If both matches are successful, we then instantiate the |
|
369 |
existential introduction rule with both the witness and predicate, solving |
|
370 |
with the matched premise. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
371 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
372 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
373 |
method solve_ex = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
374 |
(match conclusion in "\<exists>x. Q x" for Q \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
375 |
\<open>match premises in U: "Q y" for y \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
376 |
\<open>rule exI [where P = Q and x = y, OF U]\<close>\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
377 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
378 |
text \<open> |
69597 | 379 |
The first @{method match} matches the pattern \<^term>\<open>\<exists>x. Q x\<close> against the |
380 |
current conclusion, binding the term \<^term>\<open>Q\<close> in the inner match. Next |
|
61576 | 381 |
the pattern \<open>Q y\<close> is matched against all premises of the current subgoal. In |
69597 | 382 |
this case \<^term>\<open>Q\<close> is fixed and \<^term>\<open>y\<close> may be instantiated. Once a |
61576 | 383 |
match is found, the local fact \<open>U\<close> is bound to the matching premise and the |
69597 | 384 |
variable \<^term>\<open>y\<close> is bound to the matching witness. The existential |
385 |
introduction rule \<open>exI:\<close>~@{thm exI} is then instantiated with \<^term>\<open>y\<close> as |
|
386 |
the witness and \<^term>\<open>Q\<close> as the predicate, with its proof obligation |
|
61576 | 387 |
solved by the local fact U (using the Isar attribute @{attribute OF}). The |
388 |
following example is a trivial use of this method. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
389 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
390 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
391 |
lemma "halts p \<Longrightarrow> \<exists>x. halts x" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
392 |
by solve_ex |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
393 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
394 |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
395 |
subsection \<open>Operating within a focus\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
396 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
397 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
398 |
Subgoal focusing provides a structured form of a subgoal, allowing for more |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
399 |
expressive introspection of the goal state. This requires some consideration |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
400 |
in order to be used effectively. When the keyword @{keyword "premises"} is |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
401 |
given as the match target, the premises of the subgoal are lifted into |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
402 |
hypothetical theorems, which can be found and named via match patterns. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
403 |
Additionally these premises are stripped from the subgoal, leaving only the |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
404 |
conclusion. This renders them inaccessible to standard proof methods which |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
405 |
operate on the premises, such as @{method frule} or @{method erule}. Naive |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
406 |
usage of these methods within a match will most likely not function as the |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
407 |
method author intended. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
408 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
409 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
410 |
method my_allE_bad for y :: 'a = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
411 |
(match premises in I: "\<forall>x :: 'a. ?Q x" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
412 |
\<open>erule allE [where x = y]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
413 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
414 |
text \<open> |
69597 | 415 |
Here we take a single parameter \<^term>\<open>y\<close> and specialize the universal |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
416 |
elimination rule (@{thm allE}) to it, then attempt to apply this specialized |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
417 |
rule with @{method erule}. The method @{method erule} will attempt to unify |
69597 | 418 |
with a universal quantifier in the premises that matches the type of \<^term>\<open>y\<close>. Since @{keyword "premises"} causes a focus, however, there are no |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
419 |
subgoal premises to be found and thus @{method my_allE_bad} will always |
61576 | 420 |
fail. If focusing instead left the premises in place, using methods like |
421 |
@{method erule} would lead to unintended behaviour, specifically during |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
422 |
backtracking. In our example, @{method erule} could choose an alternate |
61576 | 423 |
premise while backtracking, while leaving \<open>I\<close> bound to the original match. |
424 |
In the case of more complex inner methods, where either \<open>I\<close> or bound terms |
|
425 |
are used, this would almost certainly not be the intended behaviour. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
426 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
427 |
An alternative implementation would be to specialize the elimination rule to |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
428 |
the bound term and apply it directly. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
429 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
430 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
431 |
method my_allE_almost for y :: 'a = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
432 |
(match premises in I: "\<forall>x :: 'a. ?Q x" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
433 |
\<open>rule allE [where x = y, OF I]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
434 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
435 |
lemma "\<forall>x. P x \<Longrightarrow> P y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
436 |
by (my_allE_almost y) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
437 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
438 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
439 |
This method will insert a specialized duplicate of a universally quantified |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
440 |
premise. Although this will successfully apply in the presence of such a |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
441 |
premise, it is not likely the intended behaviour. Repeated application of |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
442 |
this method will produce an infinite stream of duplicate specialized |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
443 |
premises, due to the original premise never being removed. To address this, |
61576 | 444 |
matched premises may be declared with the @{attribute thin} attribute. This |
445 |
will hide the premise from subsequent inner matches, and remove it from the |
|
446 |
list of premises when the inner method has finished and the subgoal is |
|
61493 | 447 |
unfocused. It can be considered analogous to the existing \<open>thin_tac\<close>. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
448 |
|
61576 | 449 |
To complete our example, the correct implementation of the method will |
450 |
@{attribute thin} the premise from the match and then apply it to the |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
451 |
specialized elimination rule.\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
452 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
453 |
method my_allE for y :: 'a = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
454 |
(match premises in I [thin]: "\<forall>x :: 'a. ?Q x" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
455 |
\<open>rule allE [where x = y, OF I]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
456 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
457 |
lemma "\<forall>x. P x \<Longrightarrow> \<forall>x. Q x \<Longrightarrow> P y \<and> Q y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
458 |
by (my_allE y)+ (rule conjI) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
459 |
|
61576 | 460 |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
461 |
subsubsection \<open>Inner focusing\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
462 |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
463 |
text \<open> |
61576 | 464 |
Premises are \<^emph>\<open>accumulated\<close> for the purposes of subgoal focusing. In |
465 |
contrast to using standard methods like @{method frule} within focused |
|
466 |
match, another @{method match} will have access to all the premises of the |
|
467 |
outer focus. |
|
61477 | 468 |
\<close> |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
469 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
470 |
lemma "A \<Longrightarrow> B \<Longrightarrow> A \<and> B" |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
471 |
by (match premises in H: A \<Rightarrow> \<open>intro conjI, rule H, |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
472 |
match premises in H': B \<Rightarrow> \<open>rule H'\<close>\<close>) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
473 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
474 |
text \<open> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
475 |
In this example, the inner @{method match} can find the focused premise |
69597 | 476 |
\<^term>\<open>B\<close>. In contrast, the @{method assumption} method would fail here due |
477 |
to \<^term>\<open>B\<close> not being logically accessible. |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
478 |
\<close> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
479 |
|
61576 | 480 |
lemma "A \<Longrightarrow> A \<and> (B \<longrightarrow> B)" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
481 |
by (match premises in H: A \<Rightarrow> \<open>intro conjI, rule H, rule impI, |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
482 |
match premises (local) in A \<Rightarrow> \<open>fail\<close> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
483 |
\<bar> H': B \<Rightarrow> \<open>rule H'\<close>\<close>) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
484 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
485 |
text \<open> |
69597 | 486 |
In this example, the only premise that exists in the first focus is \<^term>\<open>A\<close>. Prior to the inner match, the rule \<open>impI\<close> changes the goal \<^term>\<open>B \<longrightarrow> |
487 |
B\<close> into \<^term>\<open>B \<Longrightarrow> B\<close>. A standard premise match would also include \<^term>\<open>A\<close> as an original premise of the outer match. The \<open>local\<close> argument limits |
|
61576 | 488 |
the match to newly focused premises. |
489 |
\<close> |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
490 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
491 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
492 |
section \<open>Attributes\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
493 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
494 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
495 |
Attributes may throw errors when applied to a given fact. For example, rule |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
496 |
instantiation will fail of there is a type mismatch or if a given variable |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
497 |
doesn't exist. Within a match or a method definition, it isn't generally |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
498 |
possible to guarantee that applied attributes won't fail. For example, in |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
499 |
the following method there is no guarantee that the two provided facts will |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
500 |
necessarily compose. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
501 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
502 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
503 |
method my_compose uses rule1 rule2 = |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
504 |
(rule rule1 [OF rule2]) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
505 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
506 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
507 |
Some attributes (like @{attribute OF}) have been made partially |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
508 |
Eisbach-aware. This means that they are able to form a closure despite not |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
509 |
necessarily always being applicable. In the case of @{attribute OF}, it is |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
510 |
up to the proof author to guard attribute application with an appropriate |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
511 |
@{method match}, but there are still no static guarantees. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
512 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
513 |
In contrast to @{attribute OF}, the @{attribute "where"} and @{attribute of} |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
514 |
attributes attempt to provide static guarantees that they will apply |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
515 |
whenever possible. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
516 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
517 |
Within a match pattern for a fact, each outermost quantifier specifies the |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
518 |
requirement that a matching fact must have a schematic variable at that |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
519 |
point. This gives a corresponding name to this ``slot'' for the purposes of |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
520 |
forming a static closure, allowing the @{attribute "where"} attribute to |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
521 |
perform an instantiation at run-time. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
522 |
\<close> |
61417 | 523 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
524 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
525 |
assumes A: "Q \<Longrightarrow> False" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
526 |
shows "\<not> Q" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
527 |
by (match intros in X: "\<And>P. (P \<Longrightarrow> False) \<Longrightarrow> \<not> P" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
528 |
\<open>rule X [where P = Q, OF A]\<close>) |
61417 | 529 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
530 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
531 |
Subgoal focusing converts the outermost quantifiers of premises into |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
532 |
schematics when lifting them to hypothetical facts. This allows us to |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
533 |
instantiate them with @{attribute "where"} when using an appropriate match |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
534 |
pattern. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
535 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
536 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
537 |
lemma "(\<And>x :: 'a. A x \<Longrightarrow> B x) \<Longrightarrow> A y \<Longrightarrow> B y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
538 |
by (match premises in I: "\<And>x :: 'a. ?P x \<Longrightarrow> ?Q x" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
539 |
\<open>rule I [where x = y]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
540 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
541 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
542 |
The @{attribute of} attribute behaves similarly. It is worth noting, |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
543 |
however, that the positional instantiation of @{attribute of} occurs against |
61576 | 544 |
the position of the variables as they are declared \<^emph>\<open>in the match pattern\<close>. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
545 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
546 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
547 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
548 |
fixes A B and x :: 'a and y :: 'b |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
549 |
assumes asm: "(\<And>x y. A y x \<Longrightarrow> B x y )" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
550 |
shows "A y x \<Longrightarrow> B x y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
551 |
by (match asm in I: "\<And>(x :: 'a) (y :: 'b). ?P x y \<Longrightarrow> ?Q x y" \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
552 |
\<open>rule I [of x y]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
553 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
554 |
text \<open> |
61576 | 555 |
In this example, the order of schematics in \<open>asm\<close> is actually \<open>?y ?x\<close>, but |
556 |
we instantiate our matched rule in the opposite order. This is because the |
|
69597 | 557 |
effective rule \<^term>\<open>I\<close> was bound from the match, which declared the \<^typ>\<open>'a\<close> slot first and the \<^typ>\<open>'b\<close> slot second. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
558 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
559 |
To get the dynamic behaviour of @{attribute of} we can choose to invoke it |
61576 | 560 |
\<^emph>\<open>unchecked\<close>. This avoids trying to do any type inference for the provided |
561 |
parameters, instead storing them as their most general type and doing type |
|
562 |
matching at run-time. This, like @{attribute OF}, will throw errors if the |
|
563 |
expected slots don't exist or there is a type mismatch. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
564 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
565 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
566 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
567 |
fixes A B and x :: 'a and y :: 'b |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
568 |
assumes asm: "\<And>x y. A y x \<Longrightarrow> B x y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
569 |
shows "A y x \<Longrightarrow> B x y" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
570 |
by (match asm in I: "PROP ?P" \<Rightarrow> \<open>rule I [of (unchecked) y x]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
571 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
572 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
573 |
Attributes may be applied to matched facts directly as they are matched. Any |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
574 |
declarations will therefore be applied in the context of the inner method, |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
575 |
as well as any transformations to the rule. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
576 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
577 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
578 |
lemma "(\<And>x :: 'a. A x \<Longrightarrow> B x) \<Longrightarrow> A y \<longrightarrow> B y" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
579 |
by (match premises in I [of y, intros]: "\<And>x :: 'a. ?P x \<Longrightarrow> ?Q x" \<Rightarrow> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
580 |
\<open>prop_solver\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
581 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
582 |
text \<open> |
61576 | 583 |
In this example, the pattern \<open>\<And>x :: 'a. ?P x \<Longrightarrow> ?Q x\<close> matches against the |
69597 | 584 |
only premise, giving an appropriately typed slot for \<^term>\<open>y\<close>. After the |
585 |
match, the resulting rule is instantiated to \<^term>\<open>y\<close> and then declared as |
|
61576 | 586 |
an @{attribute intros} rule. This is then picked up by @{method prop_solver} |
587 |
to solve the goal. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
588 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
589 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
590 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
591 |
section \<open>Multi-match \label{sec:multi}\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
592 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
593 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
594 |
In all previous examples, @{method match} was only ever searching for a |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
595 |
single rule or premise. Each local fact would therefore always have a length |
61576 | 596 |
of exactly one. We may, however, wish to find \<^emph>\<open>all\<close> matching results. To |
597 |
achieve this, we can simply mark a given pattern with the \<open>(multi)\<close> |
|
598 |
argument. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
599 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
600 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
601 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
602 |
assumes asms: "A \<Longrightarrow> B" "A \<Longrightarrow> D" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
603 |
shows "(A \<longrightarrow> B) \<and> (A \<longrightarrow> D)" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
604 |
apply (match asms in I [intros]: "?P \<Longrightarrow> ?Q" \<Rightarrow> \<open>solves \<open>prop_solver\<close>\<close>)? |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
605 |
apply (match asms in I [intros]: "?P \<Longrightarrow> ?Q" (multi) \<Rightarrow> \<open>prop_solver\<close>) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
606 |
done |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
607 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
608 |
text \<open> |
69597 | 609 |
In the first @{method match}, without the \<open>(multi)\<close> argument, \<^term>\<open>I\<close> is |
61576 | 610 |
only ever be bound to one of the members of \<open>asms\<close>. This backtracks over |
611 |
both possibilities (see next section), however neither assumption in |
|
612 |
isolation is sufficient to solve to goal. The use of the @{method solves} |
|
613 |
combinator ensures that @{method prop_solver} has no effect on the goal when |
|
614 |
it doesn't solve it, and so the first match leaves the goal unchanged. In |
|
615 |
the second @{method match}, \<open>I\<close> is bound to all of \<open>asms\<close>, declaring both |
|
616 |
results as \<open>intros\<close>. With these rules @{method prop_solver} is capable of |
|
617 |
solving the goal. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
618 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
619 |
Using for-fixed variables in patterns imposes additional constraints on the |
61576 | 620 |
results. In all previous examples, the choice of using \<open>?P\<close> or a for-fixed |
69597 | 621 |
\<^term>\<open>P\<close> only depended on whether or not \<^term>\<open>P\<close> was mentioned in another |
61576 | 622 |
pattern or the inner method. When using a multi-match, however, all |
623 |
for-fixed terms must agree in the results. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
624 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
625 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
626 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
627 |
assumes asms: "A \<Longrightarrow> B" "A \<Longrightarrow> D" "D \<Longrightarrow> B" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
628 |
shows "(A \<longrightarrow> B) \<and> (A \<longrightarrow> D)" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
629 |
apply (match asms in I [intros]: "?P \<Longrightarrow> Q" (multi) for Q \<Rightarrow> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
630 |
\<open>solves \<open>prop_solver\<close>\<close>)? |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
631 |
apply (match asms in I [intros]: "P \<Longrightarrow> ?Q" (multi) for P \<Rightarrow> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
632 |
\<open>prop_solver\<close>) |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
633 |
done |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
634 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
635 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
636 |
Here we have two seemingly-equivalent applications of @{method match}, |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
637 |
however only the second one is capable of solving the goal. The first |
61576 | 638 |
@{method match} selects the first and third members of \<open>asms\<close> (those that |
639 |
agree on their conclusion), which is not sufficient. The second @{method |
|
640 |
match} selects the first and second members of \<open>asms\<close> (those that agree on |
|
641 |
their assumption), which is enough for @{method prop_solver} to solve the |
|
642 |
goal. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
643 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
644 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
645 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
646 |
section \<open>Dummy patterns\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
647 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
648 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
649 |
Dummy patterns may be given as placeholders for unique schematics in |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
650 |
patterns. They implicitly receive all currently bound variables as |
69597 | 651 |
arguments, and are coerced into the \<^typ>\<open>prop\<close> type whenever possible. For |
61576 | 652 |
example, the trivial dummy pattern \<open>_\<close> will match any proposition. In |
69597 | 653 |
contrast, by default the pattern \<open>?P\<close> is considered to have type \<^typ>\<open>bool\<close>. It will not bind anything with meta-logical connectives (e.g. \<open>_ \<Longrightarrow> _\<close> |
61576 | 654 |
or \<open>_ &&& _\<close>). |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
655 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
656 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
657 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
658 |
assumes asms: "A &&& B \<Longrightarrow> D" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
659 |
shows "(A \<and> B \<longrightarrow> D)" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
660 |
by (match asms in I: _ \<Rightarrow> \<open>prop_solver intros: I conjunctionI\<close>) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
661 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
662 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
663 |
section \<open>Backtracking\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
664 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
665 |
text \<open> |
61576 | 666 |
Patterns are considered top-down, executing the inner method \<open>m\<close> of the |
667 |
first pattern which is satisfied by the current match target. By default, |
|
668 |
matching performs extensive backtracking by attempting all valid variable |
|
669 |
and fact bindings according to the given pattern. In particular, all |
|
670 |
unifiers for a given pattern will be explored, as well as each matching |
|
61493 | 671 |
fact. The inner method \<open>m\<close> will be re-executed for each different |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
672 |
variable/fact binding during backtracking. A successful match is considered |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
673 |
a cut-point for backtracking. Specifically, once a match is made no other |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
674 |
pattern-method pairs will be considered. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
675 |
|
61576 | 676 |
The method \<open>foo\<close> below fails for all goals that are conjunctions. Any such |
677 |
goal will match the first pattern, causing the second pattern (that would |
|
678 |
otherwise match all goals) to never be considered. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
679 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
680 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
681 |
method foo = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
682 |
(match conclusion in "?P \<and> ?Q" \<Rightarrow> \<open>fail\<close> \<bar> "?R" \<Rightarrow> \<open>prop_solver\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
683 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
684 |
text \<open> |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
685 |
The failure of an inner method that is executed after a successful match |
61576 | 686 |
will cause the entire match to fail. This distinction is important due to |
687 |
the pervasive use of backtracking. When a method is used in a combinator |
|
688 |
chain, its failure becomes significant because it signals previously applied |
|
689 |
methods to move to the next result. Therefore, it is necessary for @{method |
|
690 |
match} to not mask such failure. One can always rewrite a match using the |
|
691 |
combinators ``\<open>?\<close>'' and ``\<open>|\<close>'' to try subsequent patterns in the case of an |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
692 |
inner-method failure. The following proof method, for example, always |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
693 |
invokes @{method prop_solver} for all goals because its first alternative |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
694 |
either never matches or (if it does match) always fails. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
695 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
696 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
697 |
method foo\<^sub>1 = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
698 |
(match conclusion in "?P \<and> ?Q" \<Rightarrow> \<open>fail\<close>) | |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
699 |
(match conclusion in "?R" \<Rightarrow> \<open>prop_solver\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
700 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
701 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
702 |
subsection \<open>Cut\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
703 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
704 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
705 |
Backtracking may be controlled more precisely by marking individual patterns |
61576 | 706 |
as \<open>cut\<close>. This causes backtracking to not progress beyond this pattern: once |
707 |
a match is found no others will be considered. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
708 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
709 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
710 |
method foo\<^sub>2 = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
711 |
(match premises in I: "P \<and> Q" (cut) and I': "P \<longrightarrow> ?U" for P Q \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
712 |
\<open>rule mp [OF I' I [THEN conjunct1]]\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
713 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
714 |
text \<open> |
69597 | 715 |
In this example, once a conjunction is found (\<^term>\<open>P \<and> Q\<close>), all possible |
716 |
implications of \<^term>\<open>P\<close> in the premises are considered, evaluating the |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
717 |
inner @{method rule} with each consequent. No other conjunctions will be |
61576 | 718 |
considered, with method failure occurring once all implications of the form |
719 |
\<open>P \<longrightarrow> ?U\<close> have been explored. Here the left-right processing of individual |
|
720 |
patterns is important, as all patterns after of the cut will maintain their |
|
721 |
usual backtracking behaviour. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
722 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
723 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
724 |
lemma "A \<and> B \<Longrightarrow> A \<longrightarrow> D \<Longrightarrow> A \<longrightarrow> C \<Longrightarrow> C" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
725 |
by foo\<^sub>2 |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
726 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
727 |
lemma "C \<and> D \<Longrightarrow> A \<and> B \<Longrightarrow> A \<longrightarrow> C \<Longrightarrow> C" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
728 |
by (foo\<^sub>2 | prop_solver) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
729 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
730 |
text \<open> |
61576 | 731 |
In this example, the first lemma is solved by \<open>foo\<^sub>2\<close>, by first picking |
69597 | 732 |
\<^term>\<open>A \<longrightarrow> D\<close> for \<open>I'\<close>, then backtracking and ultimately succeeding after |
733 |
picking \<^term>\<open>A \<longrightarrow> C\<close>. In the second lemma, however, \<^term>\<open>C \<and> D\<close> is |
|
61576 | 734 |
matched first, the second pattern in the match cannot be found and so the |
735 |
method fails, falling through to @{method prop_solver}. |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
736 |
|
61576 | 737 |
More precise control is also possible by giving a positive number \<open>n\<close> as an |
738 |
argument to \<open>cut\<close>. This will limit the number of backtracking results of |
|
739 |
that match to be at most \<open>n\<close>. The match argument \<open>(cut 1)\<close> is the same as |
|
740 |
simply \<open>(cut)\<close>. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
741 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
742 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
743 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
744 |
subsection \<open>Multi-match revisited\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
745 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
746 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
747 |
A multi-match will produce a sequence of potential bindings for for-fixed |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
748 |
variables, where each binding environment is the result of matching against |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
749 |
at least one element from the match target. For each environment, the match |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
750 |
result will be all elements of the match target which agree with the pattern |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
751 |
under that environment. This can result in unexpected behaviour when giving |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
752 |
very general patterns. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
753 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
754 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
755 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
756 |
assumes asms: "\<And>x. A x \<and> B x" "\<And>y. A y \<and> C y" "\<And>z. B z \<and> C z" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
757 |
shows "A x \<and> C x" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
758 |
by (match asms in I: "\<And>x. P x \<and> ?Q x" (multi) for P \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
759 |
\<open>match (P) in "A" \<Rightarrow> \<open>fail\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
760 |
\<bar> _ \<Rightarrow> \<open>match I in "\<And>x. A x \<and> B x" \<Rightarrow> \<open>fail\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
761 |
\<bar> _ \<Rightarrow> \<open>rule I\<close>\<close>\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
762 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
763 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
764 |
Intuitively it seems like this proof should fail to check. The first match |
69597 | 765 |
result, which binds \<^term>\<open>I\<close> to the first two members of \<open>asms\<close>, fails the |
766 |
second inner match due to binding \<^term>\<open>P\<close> to \<^term>\<open>A\<close>. Backtracking then |
|
767 |
attempts to bind \<^term>\<open>I\<close> to the third member of \<open>asms\<close>. This passes all |
|
61576 | 768 |
inner matches, but fails when @{method rule} cannot successfully apply this |
769 |
to the current goal. After this, a valid match that is produced by the |
|
69597 | 770 |
unifier is one which binds \<^term>\<open>P\<close> to simply \<open>\<lambda>a. A ?x\<close>. The first inner |
771 |
match succeeds because \<open>\<lambda>a. A ?x\<close> does not match \<^term>\<open>A\<close>. The next inner |
|
772 |
match succeeds because \<^term>\<open>I\<close> has only been bound to the first member of |
|
61576 | 773 |
\<open>asms\<close>. This is due to @{method match} considering \<open>\<lambda>a. A ?x\<close> and \<open>\<lambda>a. A ?y\<close> |
774 |
as distinct terms. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
775 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
776 |
The simplest way to address this is to explicitly disallow term bindings |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
777 |
which we would consider invalid. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
778 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
779 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
780 |
method abs_used for P = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
781 |
(match (P) in "\<lambda>a. ?P" \<Rightarrow> \<open>fail\<close> \<bar> _ \<Rightarrow> \<open>-\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
782 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
783 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
784 |
This method has no effect on the goal state, but instead serves as a filter |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
785 |
on the environment produced from match. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
786 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
787 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
788 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
789 |
section \<open>Uncurrying\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
790 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
791 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
792 |
The @{method match} method is not aware of the logical content of match |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
793 |
targets. Each pattern is simply matched against the shallow structure of a |
61576 | 794 |
fact or term. Most facts are in \<^emph>\<open>normal form\<close>, which curries premises via |
795 |
meta-implication \<open>_ \<Longrightarrow> _\<close>. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
796 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
797 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
798 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
799 |
assumes asms: "D \<Longrightarrow> B \<Longrightarrow> C" "D \<Longrightarrow> A" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
800 |
shows "D \<Longrightarrow> B \<Longrightarrow> C \<and> A" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
801 |
by (match asms in H: "D \<Longrightarrow> _" (multi) \<Rightarrow> \<open>prop_solver elims: H\<close>) |
61417 | 802 |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
803 |
text \<open> |
61493 | 804 |
For the first member of \<open>asms\<close> the dummy pattern successfully matches |
69597 | 805 |
against \<^term>\<open>B \<Longrightarrow> C\<close> and so the proof is successful. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
806 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
807 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
808 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
809 |
assumes asms: "A \<Longrightarrow> B \<Longrightarrow> C" "D \<Longrightarrow> C" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
810 |
shows "D \<or> (A \<and> B) \<Longrightarrow> C" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
811 |
apply (match asms in H: "_ \<Longrightarrow> C" (multi) \<Rightarrow> \<open>prop_solver elims: H\<close>)(*<*)? |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
812 |
apply (prop_solver elims: asms) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
813 |
done(*>*) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
814 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
815 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
816 |
This proof will fail to solve the goal. Our match pattern will only match |
69597 | 817 |
rules which have a single premise, and conclusion \<^term>\<open>C\<close>, so the first |
61576 | 818 |
member of \<open>asms\<close> is not bound and thus the proof fails. Matching a pattern |
69597 | 819 |
of the form \<^term>\<open>P \<Longrightarrow> Q\<close> against this fact will bind \<^term>\<open>P\<close> to |
820 |
\<^term>\<open>A\<close> and \<^term>\<open>Q\<close> to \<^term>\<open>B \<Longrightarrow> C\<close>. Our pattern, with a concrete |
|
821 |
\<^term>\<open>C\<close> in the conclusion, will fail to match this fact. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
822 |
|
61576 | 823 |
To express our desired match, we may \<^emph>\<open>uncurry\<close> our rules before matching |
824 |
against them. This forms a meta-conjunction of all premises in a fact, so |
|
825 |
that only one implication remains. For example the uncurried version of |
|
69597 | 826 |
\<^term>\<open>A \<Longrightarrow> B \<Longrightarrow> C\<close> is \<^term>\<open>A &&& B \<Longrightarrow> C\<close>. This will now match our |
61576 | 827 |
desired pattern \<open>_ \<Longrightarrow> C\<close>, and can be \<^emph>\<open>curried\<close> after the match to put it |
828 |
back into normal form. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
829 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
830 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
831 |
lemma |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
832 |
assumes asms: "A \<Longrightarrow> B \<Longrightarrow> C" "D \<Longrightarrow> C" |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
833 |
shows "D \<or> (A \<and> B) \<Longrightarrow> C" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
834 |
by (match asms [uncurry] in H [curry]: "_ \<Longrightarrow> C" (multi) \<Rightarrow> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
835 |
\<open>prop_solver elims: H\<close>) |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
836 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
837 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
838 |
section \<open>Reverse matching\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
839 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
840 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
841 |
The @{method match} method only attempts to perform matching of the pattern |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
842 |
against the match target. Specifically this means that it will not |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
843 |
instantiate schematic terms in the match target. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
844 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
845 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
846 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
847 |
assumes asms: "\<And>x :: 'a. A x" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
848 |
shows "A y" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
849 |
apply (match asms in H: "A y" \<Rightarrow> \<open>rule H\<close>)? |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
850 |
apply (match asms in H: P for P \<Rightarrow> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
851 |
\<open>match ("A y") in P \<Rightarrow> \<open>rule H\<close>\<close>) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
852 |
done |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
853 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
854 |
text \<open> |
61576 | 855 |
In the first @{method match} we attempt to find a member of \<open>asms\<close> which |
856 |
matches our goal precisely. This fails due to no such member existing. The |
|
857 |
second match reverses the role of the fact in the match, by first giving a |
|
69597 | 858 |
general pattern \<^term>\<open>P\<close>. This bound pattern is then matched against \<^term>\<open>A y\<close>. In this case, \<^term>\<open>P\<close> is bound to \<open>A ?x\<close> and so it successfully |
61576 | 859 |
matches. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
860 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
861 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
862 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
863 |
section \<open>Type matching\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
864 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
865 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
866 |
The rule instantiation attributes @{attribute "where"} and @{attribute "of"} |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
867 |
attempt to guarantee type-correctness wherever possible. This can require |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
868 |
additional invocations of @{method match} in order to statically ensure that |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
869 |
instantiation will succeed. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
870 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
871 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
872 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
873 |
assumes asms: "\<And>x :: 'a. A x" |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
874 |
shows "A y" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
875 |
by (match asms in H: "\<And>z :: 'b. P z" for P \<Rightarrow> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
876 |
\<open>match (y) in "y :: 'b" for y \<Rightarrow> \<open>rule H [where z = y]\<close>\<close>) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
877 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
878 |
text \<open> |
61576 | 879 |
In this example the type \<open>'b\<close> is matched to \<open>'a\<close>, however statically they |
880 |
are formally distinct types. The first match binds \<open>'b\<close> while the inner |
|
69597 | 881 |
match serves to coerce \<^term>\<open>y\<close> into having the type \<open>'b\<close>. This allows the |
61576 | 882 |
rule instantiation to successfully apply. |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
883 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
884 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
885 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
886 |
chapter \<open>Method development\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
887 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
888 |
section \<open>Tracing methods\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
889 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
890 |
text \<open> |
69597 | 891 |
Method tracing is supported by auxiliary print methods provided by \<^theory>\<open>HOL-Eisbach.Eisbach_Tools\<close>. These include @{method print_fact}, @{method |
68484 | 892 |
print_term} and @{method print_type}. Whenever a print method is evaluated |
893 |
it leaves the goal unchanged and writes its argument as tracing output. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
894 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
895 |
Print methods can be combined with the @{method fail} method to investigate |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
896 |
the backtracking behaviour of a method. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
897 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
898 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
899 |
lemma |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
900 |
assumes asms: A B C D |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
901 |
shows D |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
902 |
apply (match asms in H: _ \<Rightarrow> \<open>print_fact H, fail\<close>)(*<*)? |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
903 |
apply (simp add: asms) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
904 |
done(*>*) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
905 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
906 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
907 |
This proof will fail, but the tracing output will show the order that the |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
908 |
assumptions are attempted. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
909 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
910 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
911 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
912 |
section \<open>Integrating with Isabelle/ML\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
913 |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
914 |
subsubsection \<open>Attributes\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
915 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
916 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
917 |
A custom rule attribute is a simple way to extend the functionality of |
61576 | 918 |
Eisbach methods. The dummy rule attribute notation (\<open>[[ _ ]]\<close>) invokes the |
919 |
given attribute against a dummy fact and evaluates to the result of that |
|
920 |
attribute. When used as a match target, this can serve as an effective |
|
921 |
auxiliary function. |
|
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
922 |
\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
923 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
924 |
attribute_setup get_split_rule = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
925 |
\<open>Args.term >> (fn t => |
61853
fb7756087101
rule_attribute and declaration_attribute implicitly support abstract closure, but mixed_attribute implementations need to be aware of Thm.is_free_dummy;
wenzelm
parents:
61656
diff
changeset
|
926 |
Thm.rule_attribute [] (fn context => fn _ => |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
927 |
(case get_split_rule (Context.proof_of context) t of |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
928 |
SOME thm => thm |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
929 |
| NONE => Drule.dummy_thm)))\<close> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
930 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
931 |
text \<open> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
932 |
In this example, the new attribute @{attribute get_split_rule} lifts the ML |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
933 |
function of the same name into an attribute. When applied to a case |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
934 |
distinction over a datatype, it retrieves its corresponding split rule. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
935 |
|
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
936 |
We can then integrate this intro a method that applies the split rule, first |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
937 |
matching to ensure that fetching the rule was successful. |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
938 |
\<close> |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
939 |
(*<*)declare TrueI [intros](*>*) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
940 |
method splits = |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
941 |
(match conclusion in "?P f" for f \<Rightarrow> |
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
942 |
\<open>match [[get_split_rule f]] in U: "(_ :: bool) = _" \<Rightarrow> |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
943 |
\<open>rule U [THEN iffD2]\<close>\<close>) |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
944 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
945 |
lemma "L \<noteq> [] \<Longrightarrow> case L of [] \<Rightarrow> False | _ \<Rightarrow> True" |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
946 |
apply splits |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
947 |
apply (prop_solver intros: allI) |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
948 |
done |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
949 |
|
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
950 |
text \<open> |
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
951 |
Here the new @{method splits} method transforms the goal to use only logical |
69597 | 952 |
connectives: \<^term>\<open>L = [] \<longrightarrow> False \<and> (\<forall>x y. L = x # y \<longrightarrow> True)\<close>. This goal |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
953 |
is then in a form solvable by @{method prop_solver} when given the universal |
61493 | 954 |
quantifier introduction rule \<open>allI\<close>. |
60298
7c278b692aae
updated Eisbach manual, using version 3149f9146eb5 of its Bitbucket repository;
wenzelm
parents:
60288
diff
changeset
|
955 |
\<close> |
60288
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
956 |
|
d7f636331176
added Eisbach manual, using version 8845c4cb28b6 of its Bitbucket repository;
wenzelm
parents:
diff
changeset
|
957 |
end |