799 For datatypes, instances of \isa{eq} are implicitly derived |
799 For datatypes, instances of \isa{eq} are implicitly derived |
800 when possible. For other types, you may instantiate \isa{eq} |
800 when possible. For other types, you may instantiate \isa{eq} |
801 manually like any other type class. |
801 manually like any other type class. |
802 |
802 |
803 Though this \isa{eq} class is designed to get rarely in |
803 Though this \isa{eq} class is designed to get rarely in |
804 the way, a subtlety |
804 the way, in some cases the automatically derived code equations |
805 enters the stage when definitions of overloaded constants |
|
806 are dependent on operational equality. For example, let |
|
807 us define a lexicographic ordering on tuples |
|
808 (also see theory \hyperlink{theory.Product-ord}{\mbox{\isa{Product{\isacharunderscore}ord}}}):% |
|
809 \end{isamarkuptext}% |
|
810 \isamarkuptrue% |
|
811 % |
|
812 \isadelimquote |
|
813 % |
|
814 \endisadelimquote |
|
815 % |
|
816 \isatagquote |
|
817 \isacommand{instantiation}\isamarkupfalse% |
|
818 \ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}order{\isacharcomma}\ order{\isacharparenright}\ order\isanewline |
|
819 \isakeyword{begin}\isanewline |
|
820 \isanewline |
|
821 \isacommand{definition}\isamarkupfalse% |
|
822 \ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline |
|
823 \ \ {\isachardoublequoteopen}x\ {\isasymle}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isasymle}\ snd\ y{\isachardoublequoteclose}\isanewline |
|
824 \isanewline |
|
825 \isacommand{definition}\isamarkupfalse% |
|
826 \ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline |
|
827 \ \ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isacharless}\ snd\ y{\isachardoublequoteclose}\isanewline |
|
828 \isanewline |
|
829 \isacommand{instance}\isamarkupfalse% |
|
830 \ \isacommand{proof}\isamarkupfalse% |
|
831 \isanewline |
|
832 \isacommand{qed}\isamarkupfalse% |
|
833 \ {\isacharparenleft}auto\ simp{\isacharcolon}\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}prod{\isacharunderscore}def\ intro{\isacharcolon}\ order{\isacharunderscore}less{\isacharunderscore}trans{\isacharparenright}\isanewline |
|
834 \isanewline |
|
835 \isacommand{end}\isamarkupfalse% |
|
836 \isanewline |
|
837 \isanewline |
|
838 \isacommand{lemma}\isamarkupfalse% |
|
839 \ order{\isacharunderscore}prod\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline |
|
840 \ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline |
|
841 \ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline |
|
842 \ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline |
|
843 \ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline |
|
844 \ \ \isacommand{by}\isamarkupfalse% |
|
845 \ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}% |
|
846 \endisatagquote |
|
847 {\isafoldquote}% |
|
848 % |
|
849 \isadelimquote |
|
850 % |
|
851 \endisadelimquote |
|
852 % |
|
853 \begin{isamarkuptext}% |
|
854 \noindent Then code generation will fail. Why? The definition |
|
855 of \isa{op\ {\isasymle}} depends on equality on both arguments, |
|
856 which are polymorphic and impose an additional \isa{eq} |
|
857 class constraint, which the preprocessor does not propagate |
|
858 (for technical reasons). |
|
859 |
|
860 The solution is to add \isa{eq} explicitly to the first sort arguments in the |
|
861 code theorems:% |
|
862 \end{isamarkuptext}% |
|
863 \isamarkuptrue% |
|
864 % |
|
865 \isadelimquote |
|
866 % |
|
867 \endisadelimquote |
|
868 % |
|
869 \isatagquote |
|
870 \isacommand{lemma}\isamarkupfalse% |
|
871 \ order{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline |
|
872 \ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline |
|
873 \ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline |
|
874 \ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline |
|
875 \ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline |
|
876 \ \ \isacommand{by}\isamarkupfalse% |
|
877 \ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}% |
|
878 \endisatagquote |
|
879 {\isafoldquote}% |
|
880 % |
|
881 \isadelimquote |
|
882 % |
|
883 \endisadelimquote |
|
884 % |
|
885 \begin{isamarkuptext}% |
|
886 \noindent Then code generation succeeds:% |
|
887 \end{isamarkuptext}% |
|
888 \isamarkuptrue% |
|
889 % |
|
890 \isadelimquote |
|
891 % |
|
892 \endisadelimquote |
|
893 % |
|
894 \isatagquote |
|
895 % |
|
896 \begin{isamarkuptext}% |
|
897 \isatypewriter% |
|
898 \noindent% |
|
899 \hspace*{0pt}structure Example = \\ |
|
900 \hspace*{0pt}struct\\ |
|
901 \hspace*{0pt}\\ |
|
902 \hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\ |
|
903 \hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\ |
|
904 \hspace*{0pt}\\ |
|
905 \hspace*{0pt}type 'a ord = {\char123}less{\char95}eq :~'a -> 'a -> bool,~less :~'a -> 'a -> bool{\char125};\\ |
|
906 \hspace*{0pt}fun less{\char95}eq (A{\char95}:'a ord) = {\char35}less{\char95}eq A{\char95};\\ |
|
907 \hspace*{0pt}fun less (A{\char95}:'a ord) = {\char35}less A{\char95};\\ |
|
908 \hspace*{0pt}\\ |
|
909 \hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\ |
|
910 \hspace*{0pt}\\ |
|
911 \hspace*{0pt}type 'a preorder = {\char123}Orderings{\char95}{\char95}ord{\char95}preorder :~'a ord{\char125};\\ |
|
912 \hspace*{0pt}fun ord{\char95}preorder (A{\char95}:'a preorder) = {\char35}Orderings{\char95}{\char95}ord{\char95}preorder A{\char95};\\ |
|
913 \hspace*{0pt}\\ |
|
914 \hspace*{0pt}type 'a order = {\char123}Orderings{\char95}{\char95}preorder{\char95}order :~'a preorder{\char125};\\ |
|
915 \hspace*{0pt}fun preorder{\char95}order (A{\char95}:'a order) = {\char35}Orderings{\char95}{\char95}preorder{\char95}order A{\char95};\\ |
|
916 \hspace*{0pt}\\ |
|
917 \hspace*{0pt}fun less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\ |
|
918 \hspace*{0pt} ~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\ |
|
919 \hspace*{0pt} ~~~eqop A1{\char95}~x1 x2 andalso\\ |
|
920 \hspace*{0pt} ~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2\\ |
|
921 \hspace*{0pt} ~| less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\ |
|
922 \hspace*{0pt} ~~~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\ |
|
923 \hspace*{0pt} ~~~~~eqop A1{\char95}~x1 x2 andalso\\ |
|
924 \hspace*{0pt} ~~~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2;\\ |
|
925 \hspace*{0pt}\\ |
|
926 \hspace*{0pt}end;~(*struct Example*)% |
|
927 \end{isamarkuptext}% |
|
928 \isamarkuptrue% |
|
929 % |
|
930 \endisatagquote |
|
931 {\isafoldquote}% |
|
932 % |
|
933 \isadelimquote |
|
934 % |
|
935 \endisadelimquote |
|
936 % |
|
937 \begin{isamarkuptext}% |
|
938 In some cases, the automatically derived code equations |
|
939 for equality on a particular type may not be appropriate. |
805 for equality on a particular type may not be appropriate. |
940 As example, watch the following datatype representing |
806 As example, watch the following datatype representing |
941 monomorphic parametric types (where type constructors |
807 monomorphic parametric types (where type constructors |
942 are referred to by natural numbers):% |
808 are referred to by natural numbers):% |
943 \end{isamarkuptext}% |
809 \end{isamarkuptext}% |