136 where @{text "@{theory}"} is an antiquotation that is substituted with the |
136 where @{text "@{theory}"} is an antiquotation that is substituted with the |
137 current theory (remember that we assumed we are inside the theory |
137 current theory (remember that we assumed we are inside the theory |
138 @{text FirstSteps}). The name of this theory can be extracted with |
138 @{text FirstSteps}). The name of this theory can be extracted with |
139 the function @{ML "Context.theory_name"}. |
139 the function @{ML "Context.theory_name"}. |
140 |
140 |
141 Note, however, that antiquotations are statically scoped, that is the value is |
141 Note, however, that antiquotations are statically scoped, that is their value is |
142 determined at ``compile-time'', not ``run-time''. For example the function |
142 determined at ``compile-time'', not ``run-time''. For example the function |
143 *} |
143 *} |
144 |
144 |
145 ML{*fun not_current_thyname () = Context.theory_name @{theory} *} |
145 ML{*fun not_current_thyname () = Context.theory_name @{theory} *} |
146 |
146 |
152 function is called. Operationally speaking, the antiquotation @{text "@{theory}"} is |
152 function is called. Operationally speaking, the antiquotation @{text "@{theory}"} is |
153 \emph{not} replaced with code that will look up the current theory in |
153 \emph{not} replaced with code that will look up the current theory in |
154 some data structure and return it. Instead, it is literally |
154 some data structure and return it. Instead, it is literally |
155 replaced with the value representing the theory name. |
155 replaced with the value representing the theory name. |
156 |
156 |
157 In a similar way you can use antiquotations to refer to theorems: |
157 In a similar way you can use antiquotations to refer to proved theorems: |
158 |
158 |
159 @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"} |
159 @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"} |
160 |
160 |
161 or simpsets: |
161 or simpsets: |
162 |
162 |
165 val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset} |
165 val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset} |
166 in |
166 in |
167 map #name (Net.entries rules) |
167 map #name (Net.entries rules) |
168 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
168 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"} |
169 |
169 |
170 The code above extracts the theorem names that are stored in the current simpset. |
170 The code about simpsets extracts the theorem names that are stored in the |
171 We refer to the simpset with the antiquotation @{text "@{simpset}"}. |
171 current simpset. We get hold of the current simpset with the antiquotation |
172 The function @{ML rep_ss in MetaSimplifier} returns a record |
172 @{text "@{simpset}"}. The function @{ML rep_ss in MetaSimplifier} returns a record |
173 containing all information about the simpset. The rules of a simpset are stored |
173 containing all information about the simpset. The rules of a simpset are |
174 in a \emph{discrimination net} (a datastructure for fast indexing). From this net |
174 stored in a \emph{discrimination net} (a datastructure for fast |
175 we can extract the entries using the function @{ML Net.entries}. |
175 indexing). From this net we can extract the entries using the function @{ML |
|
176 Net.entries}. |
|
177 |
176 |
178 |
177 \begin{readmore} |
179 \begin{readmore} |
178 The infrastructure for simpsets is contained in @{ML_file "Pure/meta_simplifier.ML"} |
180 The infrastructure for simpsets is implemented in @{ML_file "Pure/meta_simplifier.ML"} |
179 and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented |
181 and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented |
180 in @{ML_file "Pure/net.ML"}. |
182 in @{ML_file "Pure/net.ML"}. |
181 \end{readmore} |
183 \end{readmore} |
182 |
184 |
183 While antiquotations have many applications, they were originally introduced in order |
185 While antiquotations have many applications, they were originally introduced in order |
273 |
275 |
274 |
276 |
275 section {* Constructing Terms and Types Manually *} |
277 section {* Constructing Terms and Types Manually *} |
276 |
278 |
277 text {* |
279 text {* |
278 |
280 While antiquotations are very convenient for constructing terms, they can |
279 While antiquotations are very convenient for constructing terms, |
281 only construct fixed terms (remember they are ``linked'' at |
280 they can only construct fixed terms (remember they are ``linked'' at compile-time). |
282 compile-time). See Recipe~\ref{rec:external} on Page~\pageref{rec:external} |
281 However, one often needs to construct terms |
283 for a function that pattern-matches over terms and where the pattern are |
282 dynamically. For example, a function that returns the implication |
284 constructed from antiquotations. However, one often needs to construct |
283 @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the type @{term "\<tau>"} |
285 terms dynamically. For example, a function that returns the implication |
284 as arguments can only be written as |
286 @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the type @{term |
|
287 "\<tau>"} as arguments can only be written as |
285 *} |
288 *} |
286 |
289 |
287 ML{*fun make_imp P Q tau = |
290 ML{*fun make_imp P Q tau = |
288 let |
291 let |
289 val x = Free ("x",tau) |
292 val x = Free ("x",tau) |
308 "Const \<dots> $ |
311 "Const \<dots> $ |
309 Abs (\"x\", Type (\"nat\",[]), |
312 Abs (\"x\", Type (\"nat\",[]), |
310 Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ |
313 Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ |
311 (Free (\"T\",\<dots>) $ \<dots>))"} |
314 (Free (\"T\",\<dots>) $ \<dots>))"} |
312 |
315 |
313 Whereas with @{ML make_wrong_imp} we obtain a term involving the @{term "P"} |
316 whereas with @{ML make_wrong_imp} we obtain a term involving the @{term "P"} |
314 and @{text "Q"} from the antiquotation. |
317 and @{text "Q"} from the antiquotation. |
315 |
318 |
316 @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T} @{typ nat}" |
319 @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T} @{typ nat}" |
317 "Const \<dots> $ |
320 "Const \<dots> $ |
318 Abs (\"x\", \<dots>, |
321 Abs (\"x\", \<dots>, |
319 Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ |
322 Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ |
320 (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"} |
323 (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"} |
|
324 |
|
325 (FIXME: expand the following point) |
321 |
326 |
322 One tricky point in constructing terms by hand is to obtain the fully |
327 One tricky point in constructing terms by hand is to obtain the fully |
323 qualified name for constants. For example the names for @{text "zero"} and |
328 qualified name for constants. For example the names for @{text "zero"} and |
324 @{text "+"} are more complex than one first expects, namely |
329 @{text "+"} are more complex than one first expects, namely |
325 |
330 |
388 term is well-formed, or type-checks, relative to a theory. |
393 term is well-formed, or type-checks, relative to a theory. |
389 Type-checking is done via the function @{ML cterm_of}, which converts |
394 Type-checking is done via the function @{ML cterm_of}, which converts |
390 a @{ML_type term} into a @{ML_type cterm}, a \emph{certified} term. |
395 a @{ML_type term} into a @{ML_type cterm}, a \emph{certified} term. |
391 Unlike @{ML_type term}s, which are just trees, @{ML_type |
396 Unlike @{ML_type term}s, which are just trees, @{ML_type |
392 "cterm"}s are abstract objects that are guaranteed to be |
397 "cterm"}s are abstract objects that are guaranteed to be |
393 type-correct, and they can only be constructed via the ``official |
398 type-correct, and they can only be constructed via ``official |
394 interfaces''. |
399 interfaces''. |
395 |
400 |
396 Type-checking is always relative to a theory context. For now we use |
401 Type-checking is always relative to a theory context. For now we use |
397 the @{ML "@{theory}"} antiquotation to get hold of the current theory. |
402 the @{ML "@{theory}"} antiquotation to get hold of the current theory. |
398 For example we can write |
403 For example we can write |
399 |
404 |
400 @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"} |
405 @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"} |
401 |
406 |
402 or use the antiquotation |
407 This can also be wirtten with an antiquotation |
403 |
408 |
404 @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"} |
409 @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"} |
405 |
410 |
406 Attempting to obtain the certified term for |
411 Attempting to obtain the certified term for |
407 |
412 |
503 *} |
508 *} |
504 |
509 |
505 section {* Combinators\label{sec:combinators} *} |
510 section {* Combinators\label{sec:combinators} *} |
506 |
511 |
507 text {* |
512 text {* |
508 Perhaps one of the most puzzling aspects for a beginner when reading |
513 Perhaps one of the most puzzling aspect for a beginner when reading |
509 existing Isabelle code is the liberal use of combinators. At first they |
514 existing Isabelle code special purpose combinators. At first they |
510 seem to obstruct the comprehension of the code, but after getting familiar |
515 seem to obstruct the comprehension of the code, but after getting familiar |
511 with them they actually ease the reading and also the programming. |
516 with them they actually ease the understanding and also the programming. |
512 |
517 |
513 \begin{readmore} |
518 \begin{readmore} |
514 The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"} |
519 The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"} |
515 and @{ML_file "Pure/General/basics.ML"}. |
520 and @{ML_file "Pure/General/basics.ML"}. |
516 \end{readmore} |
521 \end{readmore} |
518 The simplest combinator is @{ML I} which is just the identity function. |
523 The simplest combinator is @{ML I} which is just the identity function. |
519 *} |
524 *} |
520 |
525 |
521 ML{*fun I x = x*} |
526 ML{*fun I x = x*} |
522 |
527 |
523 text {* Another frequently used combinator is @{ML K} *} |
528 text {* Another combinator is @{ML K}, defined as *} |
524 |
529 |
525 ML{*fun K x = fn _ => x*} |
530 ML{*fun K x = fn _ => x*} |
526 |
531 |
527 text {* |
532 text {* |
528 which ``wraps'' a function around the argument @{text "x"}. This function |
533 It ``wraps'' a function around the argument @{text "x"}. However, this |
529 ignores its argument. |
534 function ignores its argument. |
530 |
535 |
531 The next combinator is reverse application defined as |
536 The next combinator is reverse application, @{ML "(op |>)"}, defined as |
532 *} |
537 *} |
533 |
538 |
534 ML{*fun x |> f = f x*} |
539 ML{*fun x |> f = f x*} |
535 |
540 |
536 text {* The purpose of this combinator is to implement functions in a |
541 text {* While just syntactic sugar for the usual function application, |
|
542 the purpose of this combinator is to implement functions in a |
537 ``waterfall fashion''. Consider for example the function *} |
543 ``waterfall fashion''. Consider for example the function *} |
538 |
544 |
539 ML %linenumbers{*fun inc_by_five x = |
545 ML %linenumbers{*fun inc_by_five x = |
540 x |> (fn x => x + 1) |
546 x |> (fn x => x + 1) |
541 |> (fn x => (x, x)) |
547 |> (fn x => (x, x)) |
545 text {* |
551 text {* |
546 which increments the argument @{text x} by 5. It does this by first incrementing |
552 which increments the argument @{text x} by 5. It does this by first incrementing |
547 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
553 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
548 the first component of the pair (Line 4) and finally incrementing the first |
554 the first component of the pair (Line 4) and finally incrementing the first |
549 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
555 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
550 common when extending theories (for example by adding a definition, followed by |
556 common when dealing with theories (for example by adding a definition, followed by |
551 lemmas and so on). Writing the function @{ML inc_by_five} using the reverse |
557 lemmas and so on). Writing the function @{ML inc_by_five} using the reverse |
552 application is much clearer than writing |
558 application is much clearer than writing |
553 *} |
559 *} |
554 |
560 |
555 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |
561 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |
557 text {* or *} |
563 text {* or *} |
558 |
564 |
559 ML{*fun inc_by_five x = |
565 ML{*fun inc_by_five x = |
560 ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*} |
566 ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*} |
561 |
567 |
562 text {* and much more economical than *} |
568 text {* and typographically more economical than *} |
563 |
569 |
564 ML{*fun inc_by_five x = |
570 ML{*fun inc_by_five x = |
565 let val y1 = x + 1 |
571 let val y1 = x + 1 |
566 val y2 = (y1, y1) |
572 val y2 = (y1, y1) |
567 val y3 = fst y2 |
573 val y3 = fst y2 |
568 val y4 = y3 + 4 |
574 val y4 = y3 + 4 |
569 in y4 end*} |
575 in y4 end*} |
570 |
576 |
571 text {* |
577 text {* |
|
578 (FIXME: give a real world example involving theories) |
|
579 |
572 Similarly, the combinator @{ML "(op #>)"} is the reverse function |
580 Similarly, the combinator @{ML "(op #>)"} is the reverse function |
573 composition. It allows us to define functions as follows |
581 composition. It can be used to define functions as follows |
574 *} |
582 *} |
575 |
583 |
576 ML{*val inc_by_six = |
584 ML{*val inc_by_six = |
577 (fn x => x + 1) |
585 (fn x => x + 1) |
578 #> (fn x => x + 2) |
586 #> (fn x => x + 2) |
587 |
595 |
588 as expected. |
596 as expected. |
589 |
597 |
590 The remaining combinators add convenience for the ``waterfall method'' |
598 The remaining combinators add convenience for the ``waterfall method'' |
591 of writing functions. The combinator @{ML tap} allows one to get |
599 of writing functions. The combinator @{ML tap} allows one to get |
592 hold of a intermediate result for some side-calculations. For |
600 hold of an intermediate result (to do some side-calculations for instance). |
593 example the function *} |
601 The function *} |
594 |
602 |
595 ML{*fun inc_by_three x = |
603 ML{*fun inc_by_three x = |
596 x |> (fn x => x + 1) |
604 x |> (fn x => x + 1) |
597 |> tap (fn x => tracing (makestring x)) |
605 |> tap (fn x => tracing (makestring x)) |
598 |> (fn x => x + 2)*} |
606 |> (fn x => x + 2)*} |
599 |
607 |
600 text {* increments the argument first by one and then by two. In the middle, |
608 text {* increments the argument first by one and then by two. In the middle, |
601 however, it prints the ``plus-one'' intermediate result inside the |
609 however, it uses @{ML tap} for printing the ``plus-one'' intermediate |
602 tracing buffer. |
610 result inside the tracing buffer. |
603 |
611 |
604 The combinator @{ML "(op `)"} is similar, but applies a function to the value |
612 The combinator @{ML "(op `)"} is similar, but applies a function to the value |
605 and returns the result together with the original value as pair. For example |
613 and returns the result together with the original value (as pair). For example |
606 the following function takes @{text x} then increments @{text x} and returns |
614 the following function takes @{text x} as argument, and then first |
607 the pair @{ML "(x + 1,x)" for x}. It then increments the right-hand component |
615 increments @{text x}, but also keeps @{text x}. The intermediate result is |
608 of the pair. |
616 therefore the pair @{ML "(x + 1,x)" for x}. The function then increments the |
|
617 right-hand component of the pair. |
609 *} |
618 *} |
610 |
619 |
611 ML{*fun inc_as_pair x = |
620 ML{*fun inc_as_pair x = |
612 x |> `(fn x => x + 1) |
621 x |> `(fn x => x + 1) |
613 |> (fn (x, y) => (x, y + 1))*} |
622 |> (fn (x, y) => (x, y + 1))*} |
614 |
623 |
615 text {* |
624 text {* |
616 The combinators @{ML "(op |>>)"} and @{ML "(op ||>)"} are defined for |
625 The combinators @{ML "(op |>>)"} and @{ML "(op ||>)"} are defined for |
617 functions manipulating pairs. The first applies the function to |
626 functions manipulating pairs. The first applies the function to |
618 the first component of the pair: |
627 the first component of the pair, defined as: |
619 *} |
628 *} |
620 |
629 |
621 ML{*fun (x, y) |>> f = (f x, y)*} |
630 ML{*fun (x, y) |>> f = (f x, y)*} |
622 |
631 |
623 text {* |
632 text {* |
624 and the second combinator to the second component: |
633 and the second combinator to the second component, defined as |
625 *} |
634 *} |
626 |
635 |
627 ML{*fun (x, y) ||> f = (x, f y)*} |
636 ML{*fun (x, y) ||> f = (x, f y)*} |
628 |
637 |
|
638 text {* |
|
639 (FIXME: find a good exercise for combinators) |
|
640 *} |
629 |
641 |
630 end |
642 end |