berghofe@41809
|
1 |
(* Title: HOL/SPARK/Examples/Gcd/Greatest_Common_Divisor.thy
|
berghofe@41809
|
2 |
Author: Stefan Berghofer
|
berghofe@41809
|
3 |
Copyright: secunet Security Networks AG
|
berghofe@41809
|
4 |
*)
|
berghofe@41809
|
5 |
|
berghofe@41809
|
6 |
theory Greatest_Common_Divisor
|
wneuper@59451
|
7 |
imports "HOL-SPARK.SPARK"
|
berghofe@41809
|
8 |
begin
|
berghofe@41809
|
9 |
|
walther@60134
|
10 |
section \<open>spark intro\<close>
|
berghofe@41809
|
11 |
spark_proof_functions
|
berghofe@41809
|
12 |
gcd = "gcd :: int \<Rightarrow> int \<Rightarrow> int"
|
berghofe@41809
|
13 |
|
walther@60102
|
14 |
declare [[ML_print_depth = 3]](* 3 7 10 9999999*)
|
walther@60096
|
15 |
|
walther@60094
|
16 |
spark_open \<open>greatest_common_divisor/g_c_d\<close> (*..from 3 files
|
walther@60095
|
17 |
./greatest_common_divisor/g_c_d.siv, *.fdl, *.rls open *.siv and
|
walther@60094
|
18 |
find the following 2 open verification conditions (VC): *)
|
berghofe@41809
|
19 |
|
walther@60134
|
20 |
section \<open>example 1\<close>
|
walther@60094
|
21 |
spark_vc procedure_g_c_d_4 (*..select 1st VC for proof: *)
|
berghofe@41809
|
22 |
proof -
|
wneuper@59324
|
23 |
from \<open>0 < d\<close> have "0 \<le> c mod d" by (rule pos_mod_sign)
|
wneuper@59324
|
24 |
with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> show ?C1
|
wneuper@59324
|
25 |
by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
|
berghofe@41809
|
26 |
next
|
wneuper@59324
|
27 |
from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> show ?C2
|
wneuper@59324
|
28 |
by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric] gcd_non_0_int)
|
berghofe@41809
|
29 |
qed
|
walther@60138
|
30 |
|
walther@60138
|
31 |
subsection \<open>observing interaction on the proof\<close>
|
walther@60134
|
32 |
text \<open>
|
walther@60138
|
33 |
:
|
walther@60134
|
34 |
# Clicks on different positions give different traces.
|
walther@60134
|
35 |
# There are blocks with equal traces (separated by \n or |)
|
walther@60134
|
36 |
proof
|
walther@60134
|
37 |
from \<open>0 < d\<close> | have "0 \<le> c mod d" | by (rule pos_mod_sign)
|
walther@60134
|
38 |
with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> | show ?C1
|
walther@60134
|
39 |
by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric])
|
walther@60134
|
40 |
next [ONLY ### Private_Output.report keyword1]
|
walther@60134
|
41 |
from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> | show ?C2
|
walther@60134
|
42 |
by (simp add: sdiv_pos_pos minus_div_mult_eq_mod [symmetric] gcd_non_0_int)
|
walther@60134
|
43 |
qed [NO TRACE]
|
walther@60134
|
44 |
# Specific traces seem to be extended by the subsequent one,
|
walther@60134
|
45 |
e.g. from \<open>0 < d\<close> extended by have "0 \<le> c mod d"
|
walther@60134
|
46 |
but both NOT by ... by (rule pos_mod_sign)
|
walther@60134
|
47 |
# Private_Output.report seems to have "" as argument frequently
|
walther@60134
|
48 |
# Output.report provided semantic annotations in Naproche;
|
walther@60138
|
49 |
thus ALL calls of Output.report (in src/Pure) are traced an show up at these elements:
|
walther@60134
|
50 |
proof x x . . .
|
walther@60134
|
51 |
from \<open>0 < d\<close> x . x x x
|
walther@60134
|
52 |
have "0 \<le> c mod d" x . x x .
|
walther@60134
|
53 |
by (rule pos_mod_sign) x x . . .
|
walther@60134
|
54 |
with \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d \<noteq> 0\<close> x . x x x
|
walther@60134
|
55 |
show ?C1 x . x x .
|
walther@60134
|
56 |
by (simp add: ...[symmetric]) x x . . .
|
walther@60134
|
57 |
next x . . . .
|
walther@60134
|
58 |
from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> x . x x x
|
walther@60134
|
59 |
show ?C2 x . x x .
|
walther@60134
|
60 |
by (simp add: ...[symmetric] gcd_non_0_int) x x . . .
|
walther@60134
|
61 |
| | | | Context_Position.report_generic
|
walther@60134
|
62 |
| | | Syntax_Phases.check_terms
|
walther@60134
|
63 |
| | Syntax_Phases.check_typs
|
walther@60134
|
64 |
| Token.syntax_generic
|
walther@60134
|
65 |
Private_Output.report
|
walther@60134
|
66 |
\<close>
|
berghofe@41809
|
67 |
|
walther@60138
|
68 |
subsection \<open>tracing calls of Output.report\<close>
|
walther@60134
|
69 |
text \<open>
|
walther@60134
|
70 |
(*--------- click on "proof -" --------
|
walther@60134
|
71 |
### Private_Output.report keyword1
|
walther@60134
|
72 |
### Private_Output.report language
|
walther@60134
|
73 |
### Private_Output.report entityo
|
walther@60134
|
74 |
### Private_Output.report operator
|
walther@60134
|
75 |
### Token.syntax_generic, Scan.error
|
walther@60134
|
76 |
### Private_Output.report
|
walther@60134
|
77 |
### Token.syntax_generic, Scan.error
|
walther@60134
|
78 |
\<close>
|
walther@60138
|
79 |
text \<open>
|
walther@60138
|
80 |
(*--------- click on "from \<open>0 < d\<close>" --------
|
walther@60138
|
81 |
### Private_Output.report keyword1
|
walther@60138
|
82 |
### Private_Output.report cartouch
|
walther@60138
|
83 |
### Private_Output.report delimite
|
walther@60138
|
84 |
### Private_Output.report entityo
|
walther@60138
|
85 |
### Syntax_Phases.check_typs
|
walther@60138
|
86 |
### Private_Output.report
|
walther@60138
|
87 |
### Syntax_Phases.check_typs
|
walther@60138
|
88 |
### Private_Output.report
|
walther@60138
|
89 |
### Syntax_Phases.check_terms
|
walther@60138
|
90 |
### Private_Output.report typingo =====
|
walther@60138
|
91 |
### Context_Position.report_generic //--- different to subsequent part below
|
walther@60138
|
92 |
### Private_Output.report entityo
|
walther@60138
|
93 |
\<close>
|
walther@60138
|
94 |
text \<open>
|
walther@60138
|
95 |
(*--------- click on "have "0 \<le> c mod d"" --------
|
walther@60138
|
96 |
### Private_Output.report keyword1
|
walther@60138
|
97 |
### Private_Output.report
|
walther@60138
|
98 |
### Private_Output.report cartouch
|
walther@60138
|
99 |
### Private_Output.report delimite
|
walther@60138
|
100 |
### Private_Output.report entityo
|
walther@60138
|
101 |
### Syntax_Phases.check_typs
|
walther@60138
|
102 |
### Private_Output.report
|
walther@60138
|
103 |
### Syntax_Phases.check_typs
|
walther@60138
|
104 |
### Private_Output.report
|
walther@60138
|
105 |
### Syntax_Phases.check_terms
|
walther@60138
|
106 |
### Private_Output.report typingo =====
|
walther@60138
|
107 |
### Syntax_Phases.check_typs //--- different to previous part above
|
walther@60138
|
108 |
### Private_Output.report
|
walther@60138
|
109 |
### Syntax_Phases.check_terms
|
walther@60138
|
110 |
### Private_Output.report
|
walther@60138
|
111 |
\<close>
|
walther@60138
|
112 |
|
walther@60138
|
113 |
subsection \<open>signatures of the traced callers of Private_Output.report\<close>
|
walther@60138
|
114 |
ML \<open>
|
walther@60138
|
115 |
\<close> ML \<open>
|
walther@60138
|
116 |
Private_Output.report : string(*= markup*) list -> unit;
|
walther@60138
|
117 |
Context_Position.report_generic: Context.generic -> Position.T -> Markup.T -> unit;
|
walther@60138
|
118 |
Token.syntax_generic : 'a Token.context_parser -> Token.src -> Context.generic ->
|
walther@60138
|
119 |
'a * Context.generic;
|
walther@60138
|
120 |
(*Syntax_Phases.check_typs : Proof.context -> typ list -> typ list; ..local*)
|
walther@60138
|
121 |
(*Syntax_Phases.check_terms : Proof.context -> term list -> term list; ..local*)
|
walther@60138
|
122 |
\<close> ML \<open>
|
walther@60138
|
123 |
\<close>
|
walther@60138
|
124 |
|
walther@60138
|
125 |
subsection \<open>lookup calls of Syntax_Phases.check_terms\<close>
|
walther@60138
|
126 |
text \<open>
|
walther@60138
|
127 |
focus are "from \<open>0 < d\<close>" and have "0 \<le> c mod d".
|
walther@60138
|
128 |
|
walther@60138
|
129 |
encapsulation?:
|
walther@60138
|
130 |
Syntax_Phases.check_terms NOwhere in src/Pure,
|
walther@60138
|
131 |
check_terms occurs in Theory.setup (Syntax.install_operations {..check_terms = check_terms..}
|
walther@60138
|
132 |
and nowhere else (except fun check_props)
|
walther@60138
|
133 |
so the calls are Syntax.check_terms ? -- NO: calls.1..4 --vv pop up in NONE of the 3 traces above.
|
walther@60138
|
134 |
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
walther@60138
|
135 |
but they seem to be identical:
|
walther@60138
|
136 |
Syntax_Phases.check_terms: Proof.context -> term list -> term list;
|
walther@60138
|
137 |
Syntax.check_terms: Proof.context -> term list -> term list;
|
walther@60138
|
138 |
?! there are 3-times structure Syntax:
|
walther@60138
|
139 |
Pure/Syntax/lexicon.ML /NO check_terms/
|
walther@60138
|
140 |
signature LEXICON = sig structure Syntax: sig val const: string -> term ..
|
walther@60138
|
141 |
Pure/Syntax/syntax.ML
|
walther@60138
|
142 |
type operations = {..., ..., check_terms: Proof.context -> term list -> term list, ..
|
walther@60138
|
143 |
val check_terms = operation #check_terms;
|
walther@60138
|
144 |
Pure/Syntax/syntax_trans.ML /NO check_terms/
|
walther@60138
|
145 |
|
walther@60138
|
146 |
the ASSUMED callers of Syntax.check_terms:
|
walther@60138
|
147 |
// Pure/Isar/expression.ML
|
walther@60138
|
148 |
// 1,val inst_morphism: (string * typ) list -> (string * bool) * term list -> Proof.context ->
|
walther@60138
|
149 |
// morphism * Proof.context
|
walther@60138
|
150 |
// 2.val check_autofix:
|
walther@60138
|
151 |
// ('a * ('b * term list)) list ->
|
walther@60138
|
152 |
// ('c * term) list list ->
|
walther@60138
|
153 |
// (typ, term, 'd) ctxt list ->
|
walther@60138
|
154 |
// ('e * (term * term list) list) list -> Proof.context ->
|
walther@60138
|
155 |
// (('a * ('b * term list)) list * ('c * term) list list * (typ, term, 'd) ctxt list *
|
walther@60138
|
156 |
// ('e * (term * term list) list) list) * Proof.context
|
walther@60138
|
157 |
// val check: (term * term list) list -> Proof.context ->
|
walther@60138
|
158 |
// (term * term list) list * Proof.context
|
walther@60138
|
159 |
// Pure/Isar/obtain.ML
|
walther@60138
|
160 |
// 3.val Obtain.read_obtains: Proof.context -> term -> Element.obtains -> (binding * term) list
|
walther@60138
|
161 |
// Pure/Isar/proof.ML
|
walther@60138
|
162 |
// 4.val let_bind: (term list * term) list -> state -> state
|
walther@60138
|
163 |
// 5.val let_bind_cmd: (string list * string) list -> state -> state
|
walther@60138
|
164 |
// val read_terms: context -> typ -> string list -> term list
|
walther@60138
|
165 |
// Pure/Isar/proof_context.ML
|
walther@60138
|
166 |
// 6.val infer_type: Proof.context -> string * typ -> typ
|
walther@60138
|
167 |
// Pure/simplifier.ML
|
walther@60138
|
168 |
// 7.val Simplifier.define_simproc: binding -> term Simplifier.simproc_spec ->
|
walther@60138
|
169 |
// local_theory -> local_theory
|
walther@60138
|
170 |
// Pure/Tools/rule_insts.ML
|
walther@60138
|
171 |
// 8.val Rule_Insts.read_term: string -> Proof.context -> term * Proof.context
|
walther@60138
|
172 |
// :
|
walther@60138
|
173 |
// 1.. looked up in the sequel
|
walther@60138
|
174 |
\<close>
|
walther@60138
|
175 |
subsection \<open>lookup Syntax.check_terms -> *1..4\<close>
|
walther@60138
|
176 |
text \<open>\<close>
|
walther@60138
|
177 |
|
walther@60138
|
178 |
subsubsection \<open>lookup 1* -> Expression.inst_morphism\<close>
|
walther@60138
|
179 |
text \<open>\<close>
|
walther@60138
|
180 |
|
walther@60138
|
181 |
subsubsection \<open>lookup 2* -> Expression.check_autofix\<close>
|
walther@60138
|
182 |
text \<open>
|
walther@60138
|
183 |
\<close>
|
walther@60138
|
184 |
subsubsection \<open>lookup 3* -> Obtain.read_obtains\<close>
|
walther@60138
|
185 |
text \<open>\<close>
|
walther@60138
|
186 |
|
walther@60138
|
187 |
subsubsection \<open>lookup 4* -> Proof.let_bind\<close>
|
walther@60138
|
188 |
text \<open>\<close>
|
walther@60138
|
189 |
|
walther@60138
|
190 |
subsubsection \<open>lookup 5* -> Proof.let_bind_cmd\<close>
|
walther@60138
|
191 |
text \<open>\<close>
|
walther@60138
|
192 |
|
walther@60138
|
193 |
subsubsection \<open>lookup 6* -> Proof_Context.infer_type\<close>
|
walther@60138
|
194 |
text \<open>\<close>
|
walther@60138
|
195 |
|
walther@60138
|
196 |
subsubsection \<open>lookup 7* -> Simplifier.define_simproc\<close>
|
walther@60138
|
197 |
text \<open>\<close>
|
walther@60138
|
198 |
|
walther@60138
|
199 |
subsubsection \<open>lookup 8* -> Rule_Insts.read_term\<close>
|
walther@60138
|
200 |
text \<open>\<close>
|
walther@60138
|
201 |
|
walther@60134
|
202 |
|
walther@60134
|
203 |
section \<open>example 2\<close>
|
walther@60138
|
204 |
|
walther@60094
|
205 |
spark_vc procedure_g_c_d_11 (*..select 2nd VC for proof: *)
|
berghofe@41809
|
206 |
proof -
|
wneuper@59324
|
207 |
from \<open>0 \<le> c\<close> \<open>0 < d\<close> \<open>c - c sdiv d * d = 0\<close>
|
berghofe@41809
|
208 |
have "d dvd c"
|
haftmann@58856
|
209 |
by (auto simp add: sdiv_pos_pos dvd_def ac_simps)
|
wneuper@59324
|
210 |
with \<open>0 < d\<close> \<open>gcd c d = gcd m n\<close> show ?C1
|
berghofe@41809
|
211 |
by simp
|
berghofe@41809
|
212 |
qed
|
berghofe@41809
|
213 |
|
berghofe@41809
|
214 |
spark_end
|
berghofe@41809
|
215 |
|
berghofe@41809
|
216 |
end
|