560 need to be programmed. While this is not difficult to do on the ML-level, |
560 need to be programmed. While this is not difficult to do on the ML-level, |
561 new commands, in order to be useful, need to be recognised by |
561 new commands, in order to be useful, need to be recognised by |
562 ProofGeneral. This results in some subtle configuration issues, which we |
562 ProofGeneral. This results in some subtle configuration issues, which we |
563 will explain in this section. |
563 will explain in this section. |
564 |
564 |
565 Let us start with a ``silly'' command, below named \isacommand{foo}, which does nothing at all. |
565 Let us start with a ``silly'' command, which we call \isacommand{foo} in what follows. |
566 On the ML-level it can be defined as |
566 To keep things simple this command does nothing at all. On the ML-level it can be defined as |
567 |
567 |
568 @{ML [display] |
568 @{ML [display] |
569 "let |
569 "let |
570 val do_nothing = Scan.succeed (Toplevel.theory (fn x => x)) |
570 val do_nothing = Scan.succeed (Toplevel.theory (fn x => x)) |
571 val flag = OuterKeyword.thy_decl |
571 val flag = OuterKeyword.thy_decl |
572 in |
572 in |
573 OuterSyntax.command \"foo\" \"description of foo\" flag do_nothing |
573 OuterSyntax.command \"foo\" \"description of foo\" flag do_nothing |
574 end"} |
574 end"} |
575 |
575 |
576 The function @{ML OuterSyntax.command} expects a name for the command, a |
576 The function @{ML OuterSyntax.command} expects a name for the command, a |
577 short description, a flag (which we will explain it later on more thoroughly) and a |
577 short description, a flag (which we will explain later on more thoroughly) and a |
578 parser for a top-level transition function (its purpose will also explained |
578 parser for a top-level transition function (its purpose will also explained |
579 later). |
579 later). |
580 |
580 |
581 While this is everything we have to do on the ML-level, we need |
581 While this is everything we have to do on the ML-level, we need |
582 now a keyword file that can be loaded by ProofGeneral. This is to enable ProofGeneral |
582 now a keyword file that can be loaded by ProofGeneral. This is to enable ProofGeneral |
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
616 |
616 |
617 For |
617 For |
618 our purposes it is sufficient to use the log files for the theories @{text "Pure"}, |
618 our purposes it is sufficient to use the log files for the theories @{text "Pure"}, |
619 @{text "HOL"} and @{text "Pure-ProofGeneral"}, as well as the theory @{text "Command.thy"} |
619 @{text "HOL"} and @{text "Pure-ProofGeneral"}, as well as the theory @{text "Command.thy"} |
620 containing the new command. @{text Pure} and @{text HOL} are usually compiled during the |
620 containing the new \isacommand{foo}-command. @{text Pure} and @{text HOL} are usually compiled during the |
621 installation of Isabelle. So log files for them are already available. If not, then they |
621 installation of Isabelle. So log files for them are already available. If not, then they |
622 can be conveniently compiled using build-script from the distribution |
622 can be conveniently compiled using build-script from the distribution |
623 |
623 |
624 @{text [display] |
624 @{text [display] |
625 "$ ./build -m \"Pure\" |
625 "$ ./build -m \"Pure\" |
646 We need to copy the file @{text "Command.thy"} into the directory @{text "FooCommand"} |
646 We need to copy the file @{text "Command.thy"} into the directory @{text "FooCommand"} |
647 and add the line |
647 and add the line |
648 |
648 |
649 @{text [display] "use_thy \"Command\";"} |
649 @{text [display] "use_thy \"Command\";"} |
650 |
650 |
651 to the file @{text "./FooCommand/ROOT.ML"}. Now we can compile the theory by just typing |
651 to the file @{text "./FooCommand/ROOT.ML"}. We can now compile the theory by just typing |
652 |
652 |
653 @{text [display] "$ isabelle make"} |
653 @{text [display] "$ isabelle make"} |
654 |
654 |
655 We created now the necessary log files. They are typically stored |
655 We created finally all the necessary log files. They are typically stored |
656 in the directory |
656 in the directory |
657 |
657 |
658 @{text [display] "~/.isabelle/heaps/Isabelle2008/polyml-5.2.1_x86-linux/log"} |
658 @{text [display] "~/.isabelle/heaps/Isabelle2008/polyml-5.2.1_x86-linux/log"} |
659 |
659 |
660 or something similar depending on your Isabelle distribution and architecture. |
660 or something similar depending on your Isabelle distribution and architecture. |
669 "Pure.gz |
669 "Pure.gz |
670 HOL.gz |
670 HOL.gz |
671 Pure-ProofGeneral.gz |
671 Pure-ProofGeneral.gz |
672 HOL-FooCommand.gz"} |
672 HOL-FooCommand.gz"} |
673 |
673 |
674 We can now create the keyword file with |
674 They are used for creating the keyword files with the command |
675 |
675 |
676 @{text [display] |
676 @{text [display] |
677 "$ isabelle keywords -k foo |
677 "$ isabelle keywords -k foo |
678 `$ISABELLE_LOGS/{Pure.gz,HOL.gz,Pure-ProofGeneral,HOL-FooCommand.gz}`"} |
678 $ISABELLE_LOGS/{Pure.gz,HOL.gz,Pure-ProofGeneral.gz,HOL-FooCommand.gz}"} |
679 |
679 |
680 The result is the file @{text "isar-keywords-foo.el"}, which needs to be |
680 The result is the file @{text "isar-keywords-foo.el"}. This file needs to be |
681 copied to the directory @{text "~/.isabelle/etc"}. To make Isabelle use |
681 copied to the directory @{text "~/.isabelle/etc"}. To make Isabelle use |
682 this keyword file, we need to start it with the option @{text "-k foo"}, i.e. |
682 this keyword file, we have to start it with the option @{text "-k foo"}, i.e. |
683 |
683 |
684 @{text [display] "isabelle -k foo <a-theory-file>"} |
684 @{text [display] "isabelle -k foo <a-theory-file>"} |
685 |
685 |
686 If we now run the original code |
686 If we now run the original code |
687 |
687 |
691 val flag = OuterKeyword.thy_decl |
691 val flag = OuterKeyword.thy_decl |
692 in |
692 in |
693 OuterSyntax.command \"foo\" \"description of foo\" flag do_nothing |
693 OuterSyntax.command \"foo\" \"description of foo\" flag do_nothing |
694 end"} |
694 end"} |
695 |
695 |
696 then we can finally make use of \isacommand{foo}! Similarly |
696 then we can make use of \isacommand{foo}! Similarly with any other new command. |
697 with any other command you want to implement. |
|
698 |
697 |
699 In the example above, we built the theories on top of the HOL-logic. If you |
698 In the example above, we built the theories on top of the HOL-logic. If you |
700 target other logics, such as Nominal or ZF, then you need to change the |
699 target other logics, such as Nominal or ZF, then you need to change the |
701 log files appropriately. |
700 log files appropriately. |
702 |
701 |