517 section {* Theorem Attributes *} |
517 section {* Theorem Attributes *} |
518 |
518 |
519 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *} |
519 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *} |
520 |
520 |
521 text {* |
521 text {* |
522 It will often be necesseary to inspect terms, cterms or theorems. Isabelle |
522 You will occationally feel the need to inspect terms, cterms or theorems during |
523 contains elaborate pretty-printing functions for that, but for quick-and-dirty |
523 development. Isabelle contains elaborate pretty-printing functions for that, but |
524 solutions they are too unwieldy. A term can be transformed into a string using |
524 for quick-and-dirty solutions they are way too unwieldy. A simple way to transform |
525 the function @{ML Syntax.string_of_term} |
525 a term into a string is to use the function @{ML Syntax.string_of_term}. |
526 |
526 |
527 @{ML_response_fake [display,gray] |
527 @{ML_response_fake [display,gray] |
528 "Syntax.string_of_term @{context} @{term \"1::nat\"}" |
528 "Syntax.string_of_term @{context} @{term \"1::nat\"}" |
529 "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""} |
529 "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""} |
530 |
530 |
531 This produces a string, though with printing directions encoded in it. This |
531 This produces a string, though with printing directions encoded in it. The string |
532 can be properly printed, when enclosed in a @{ML warning} |
532 can be properly printed, when enclosed in a @{ML warning}. |
533 |
533 |
534 @{ML_response_fake [display,gray] |
534 @{ML_response_fake [display,gray] |
535 "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})" |
535 "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})" |
536 "\"1\""} |
536 "\"1\""} |
537 |
537 |
538 A @{ML_type cterm} can be transformed into a string by the function: |
538 A @{ML_type cterm} can be transformed into a string by the following function. |
539 *} |
539 *} |
540 |
540 |
541 ML{*fun str_of_cterm ctxt t = |
541 ML{*fun str_of_cterm ctxt t = |
542 Syntax.string_of_term ctxt (term_of t)*} |
542 Syntax.string_of_term ctxt (term_of t)*} |
543 |
543 |
544 text {* |
544 text {* |
545 If there are more than one @{ML_type cterm} to be printed, we can use the function |
545 If there are more than one @{ML_type cterm} to be printed, you can use the function |
546 @{ML commas} to conveniently separate them. |
546 @{ML commas} to conveniently separate them. |
547 *} |
547 *} |
548 |
548 |
549 ML{*fun str_of_cterms ctxt ts = |
549 ML{*fun str_of_cterms ctxt ts = |
550 commas (map (str_of_cterm ctxt) ts)*} |
550 commas (map (str_of_cterm ctxt) ts)*} |
551 |
551 |
552 text {* |
552 text {* |
553 The easiest way to get the string of a theorem, is to transform it |
553 The easiest way to get the string of a theorem is to transform it |
554 into a @{ML_type cterm} using the function @{ML crep_thm}. |
554 into a @{ML_type cterm} using the function @{ML crep_thm}. |
555 *} |
555 *} |
556 |
556 |
557 ML{*fun str_of_thm ctxt thm = |
557 ML{*fun str_of_thm ctxt thm = |
558 let |
558 let |
602 actually ease the understanding and also the programming. |
602 actually ease the understanding and also the programming. |
603 |
603 |
604 \begin{readmore} |
604 \begin{readmore} |
605 The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"} |
605 The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"} |
606 and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} |
606 and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} |
607 contains further information about combinators. |
607 contains further information about them. |
608 \end{readmore} |
608 \end{readmore} |
609 |
609 |
610 The simplest combinator is @{ML I}, which is just the identity function. |
610 The simplest combinator is @{ML I}, which is just the identity function. |
611 *} |
611 *} |
612 |
612 |
616 |
616 |
617 ML{*fun K x = fn _ => x*} |
617 ML{*fun K x = fn _ => x*} |
618 |
618 |
619 text {* |
619 text {* |
620 @{ML K} ``wraps'' a function around the argument @{text "x"}. However, this |
620 @{ML K} ``wraps'' a function around the argument @{text "x"}. However, this |
621 function ignores its argument. As a result @{ML K} defines a constant function |
621 function ignores its argument. As a result, @{ML K} defines a constant function |
622 returning @{text x}. |
622 returning @{text x}. |
623 |
623 |
624 The next combinator is reverse application, @{ML "|>"}, defined as |
624 The next combinator is reverse application, @{ML "|>"}, defined as: |
625 *} |
625 *} |
626 |
626 |
627 ML{*fun x |> f = f x*} |
627 ML{*fun x |> f = f x*} |
628 |
628 |
629 text {* While just syntactic sugar for the usual function application, |
629 text {* While just syntactic sugar for the usual function application, |
640 which increments the argument @{text x} by 5. It does this by first incrementing |
640 which increments the argument @{text x} by 5. It does this by first incrementing |
641 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
641 the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking |
642 the first component of the pair (Line 4) and finally incrementing the first |
642 the first component of the pair (Line 4) and finally incrementing the first |
643 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
643 component by 4 (Line 5). This kind of cascading manipulations of values is quite |
644 common when dealing with theories (for example by adding a definition, followed by |
644 common when dealing with theories (for example by adding a definition, followed by |
645 lemmas and so on). The reverse application allows you to read what happens inside |
645 lemmas and so on). The reverse application allows you to read what happens in |
646 the function in a top-down manner. This kind of codeing should also be familiar, |
646 a top-down manner. This kind of coding should also be familiar, |
647 if you used Haskell's do-notation. Writing the function @{ML inc_by_five} using |
647 if you used Haskell's do-notation. Writing the function @{ML inc_by_five} using |
648 the reverse application is much clearer than writing |
648 the reverse application is much clearer than writing |
649 *} |
649 *} |
650 |
650 |
651 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |
651 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*} |