241 cumbersome and inelegant in light of our work, which can deal with such |
241 cumbersome and inelegant in light of our work, which can deal with such |
242 definitions directly. The solution is that we need to build aggregate |
242 definitions directly. The solution is that we need to build aggregate |
243 representation and abstraction functions, which in case of @{text "\<Union>"} |
243 representation and abstraction functions, which in case of @{text "\<Union>"} |
244 generate the following definition |
244 generate the following definition |
245 |
245 |
246 @{text [display, indent=10] "\<Union> S \<equiv> Abs_fset (flat ((map Rep_fset \<circ> Rep_fset) S))"} |
246 @{text [display, indent=10] "\<Union> S \<equiv> Abs_fset (flat ((map_list Rep_fset \<circ> Rep_fset) S))"} |
247 |
247 |
248 \noindent |
248 \noindent |
249 where @{term map} is the usual mapping function for lists. In this paper we |
249 where @{term map_list} is the usual mapping function for lists. In this paper we |
250 will present a formal definition of our aggregate abstraction and |
250 will present a formal definition of our aggregate abstraction and |
251 representation functions (this definition was omitted in \cite{Homeier05}). |
251 representation functions (this definition was omitted in \cite{Homeier05}). |
252 They generate definitions, like the one above for @{text "\<Union>"}, |
252 They generate definitions, like the one above for @{text "\<Union>"}, |
253 according to the type of the raw constant and the type |
253 according to the type of the raw constant and the type |
254 of the quotient constant. This means we also have to extend the notions |
254 of the quotient constant. This means we also have to extend the notions |
310 rules). As a result we are able to define automatic proof |
310 rules). As a result we are able to define automatic proof |
311 procedures showing that one theorem implies another by decomposing the term |
311 procedures showing that one theorem implies another by decomposing the term |
312 underlying the first theorem. |
312 underlying the first theorem. |
313 |
313 |
314 Like Homeier's, our work relies on map-functions defined for every type |
314 Like Homeier's, our work relies on map-functions defined for every type |
315 constructor taking some arguments, for example @{text map} for lists. Homeier |
315 constructor taking some arguments, for example @{text map_list} for lists. Homeier |
316 describes in \cite{Homeier05} map-functions for products, sums, options and |
316 describes in \cite{Homeier05} map-functions for products, sums, options and |
317 also the following map for function types |
317 also the following map for function types |
318 |
318 |
319 @{thm [display, indent=10] fun_map_def[no_vars, THEN eq_reflection]} |
319 @{thm [display, indent=10] fun_map_def[no_vars, THEN eq_reflection]} |
320 |
320 |
412 quotient theorem for composing particular quotient relations. |
412 quotient theorem for composing particular quotient relations. |
413 For example, to lift theorems involving @{term flat} the quotient theorem for |
413 For example, to lift theorems involving @{term flat} the quotient theorem for |
414 composing @{text "\<approx>\<^bsub>list\<^esub>"} will be necessary: given @{term "Quotient R Abs Rep"} |
414 composing @{text "\<approx>\<^bsub>list\<^esub>"} will be necessary: given @{term "Quotient R Abs Rep"} |
415 with @{text R} being an equivalence relation, then |
415 with @{text R} being an equivalence relation, then |
416 |
416 |
417 @{text [display, indent=10] "Quotient (rel_list R \<circ>\<circ>\<circ> \<approx>\<^bsub>list\<^esub>) (Abs_fset \<circ> map Abs) (map Rep \<circ> Rep_fset)"} |
417 @{text [display, indent=2] "Quotient (rel_list R \<circ>\<circ>\<circ> \<approx>\<^bsub>list\<^esub>) (Abs_fset \<circ> map_list Abs) (map_list Rep \<circ> Rep_fset)"} |
418 |
418 |
419 \vspace{-.5mm} |
419 \vspace{-.5mm} |
420 *} |
420 *} |
421 |
421 |
422 section {* Quotient Types and Quotient Definitions\label{sec:type} *} |
422 section {* Quotient Types and Quotient Definitions\label{sec:type} *} |
541 @{text "ABS (\<sigma>\<^isub>1 \<Rightarrow> \<sigma>\<^isub>2, \<tau>\<^isub>1 \<Rightarrow> \<tau>\<^isub>2)"} & $\dn$ & @{text "REP (\<sigma>\<^isub>1, \<tau>\<^isub>1) \<singlearr> ABS (\<sigma>\<^isub>2, \<tau>\<^isub>2)"}\\ |
541 @{text "ABS (\<sigma>\<^isub>1 \<Rightarrow> \<sigma>\<^isub>2, \<tau>\<^isub>1 \<Rightarrow> \<tau>\<^isub>2)"} & $\dn$ & @{text "REP (\<sigma>\<^isub>1, \<tau>\<^isub>1) \<singlearr> ABS (\<sigma>\<^isub>2, \<tau>\<^isub>2)"}\\ |
542 @{text "REP (\<sigma>\<^isub>1 \<Rightarrow> \<sigma>\<^isub>2, \<tau>\<^isub>1 \<Rightarrow> \<tau>\<^isub>2)"} & $\dn$ & @{text "ABS (\<sigma>\<^isub>1, \<tau>\<^isub>1) \<singlearr> REP (\<sigma>\<^isub>2, \<tau>\<^isub>2)"}\smallskip\\ |
542 @{text "REP (\<sigma>\<^isub>1 \<Rightarrow> \<sigma>\<^isub>2, \<tau>\<^isub>1 \<Rightarrow> \<tau>\<^isub>2)"} & $\dn$ & @{text "ABS (\<sigma>\<^isub>1, \<tau>\<^isub>1) \<singlearr> REP (\<sigma>\<^isub>2, \<tau>\<^isub>2)"}\smallskip\\ |
543 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
543 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
544 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (ABS (\<sigma>s, \<tau>s))"}\\ |
544 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (ABS (\<sigma>s, \<tau>s))"}\\ |
545 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (REP (\<sigma>s, \<tau>s))"}\smallskip\\ |
545 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (REP (\<sigma>s, \<tau>s))"}\smallskip\\ |
546 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors:}\\ |
546 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors with @{text "\<alpha>s |
|
547 \<kappa>\<^isub>q"} being the quotient of the raw type @{text "\<rho>s \<kappa>"}:}\\ |
547 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "Abs_\<kappa>\<^isub>q \<circ> (MAP(\<rho>s \<kappa>) (ABS (\<sigma>s', \<tau>s)))"}\\ |
548 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "Abs_\<kappa>\<^isub>q \<circ> (MAP(\<rho>s \<kappa>) (ABS (\<sigma>s', \<tau>s)))"}\\ |
548 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "(MAP(\<rho>s \<kappa>) (REP (\<sigma>s', \<tau>s))) \<circ> Rep_\<kappa>\<^isub>q"} |
549 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "(MAP(\<rho>s \<kappa>) (REP (\<sigma>s', \<tau>s))) \<circ> Rep_\<kappa>\<^isub>q"} |
549 \end{tabular}\hfill\numbered{ABSREP} |
550 \end{tabular}\hfill\numbered{ABSREP} |
550 \end{center} |
551 \end{center} |
551 % |
552 % |
552 \noindent |
553 \noindent |
553 In the last two clauses we have that the type @{text "\<alpha>s |
554 In the last two clauses we rely on the fact that the type @{text "\<alpha>s |
554 \<kappa>\<^isub>q"} is the quotient of the raw type @{text "\<rho>s \<kappa>"} (for example |
555 \<kappa>\<^isub>q"} is the quotient of the raw type @{text "\<rho>s \<kappa>"} (for example |
555 @{text "int"} and @{text "nat \<times> nat"}, or @{text "\<alpha> fset"} and @{text "\<alpha> |
556 @{text "int"} and @{text "nat \<times> nat"}, or @{text "\<alpha> fset"} and @{text "\<alpha> |
556 list"}). The quotient construction ensures that the type variables in @{text |
557 list"}). The quotient construction ensures that the type variables in @{text |
557 "\<rho>s"} must be among the @{text "\<alpha>s"}. The @{text "\<sigma>s'"} are given by the |
558 "\<rho>s \<kappa>"} must be among the @{text "\<alpha>s"}. The @{text "\<sigma>s'"} are given by the |
558 matchers for the @{text "\<alpha>s"} when matching @{text "\<rho>s \<kappa>"} against |
559 substitutions for the @{text "\<alpha>s"} when matching @{text "\<sigma>s \<kappa>"} against |
559 @{text "\<sigma>s \<kappa>"}. The |
560 @{text "\<rho>s \<kappa>"}. The |
560 function @{text "MAP"} calculates an \emph{aggregate map-function} for a raw |
561 function @{text "MAP"} calculates an \emph{aggregate map-function} for a raw |
561 type as follows: |
562 type as follows: |
562 % |
563 % |
563 \begin{center} |
564 \begin{center} |
564 \begin{tabular}{rcl} |
565 \begin{tabular}{rcl} |
577 The need for aggregate map-functions can be seen in cases where we build quotients, |
578 The need for aggregate map-functions can be seen in cases where we build quotients, |
578 say @{text "(\<alpha>, \<beta>) \<kappa>\<^isub>q"}, out of compound raw types, say @{text "(\<alpha> list) \<times> \<beta>"}. |
579 say @{text "(\<alpha>, \<beta>) \<kappa>\<^isub>q"}, out of compound raw types, say @{text "(\<alpha> list) \<times> \<beta>"}. |
579 In this case @{text MAP} generates the |
580 In this case @{text MAP} generates the |
580 aggregate map-function: |
581 aggregate map-function: |
581 |
582 |
582 @{text [display, indent=10] "\<lambda>a b. map_prod (map a) b"} |
583 @{text [display, indent=10] "\<lambda>a b. map_prod (map_list a) b"} |
583 |
584 |
584 \noindent |
585 \noindent |
585 which is essential in order to define the corresponding aggregate |
586 which is essential in order to define the corresponding aggregate |
586 abstraction and representation functions. |
587 abstraction and representation functions. |
587 |
588 |
589 example about @{term "concat"} and @{term "fconcat"}, where we have the raw type |
590 example about @{term "concat"} and @{term "fconcat"}, where we have the raw type |
590 @{text "(\<alpha> list) list \<Rightarrow> \<alpha> list"} and the quotient type @{text "(\<alpha> fset) fset \<Rightarrow> \<alpha> |
591 @{text "(\<alpha> list) list \<Rightarrow> \<alpha> list"} and the quotient type @{text "(\<alpha> fset) fset \<Rightarrow> \<alpha> |
591 fset"}. Feeding these types into @{text ABS} gives us (after some @{text "\<beta>"}-simplifications) |
592 fset"}. Feeding these types into @{text ABS} gives us (after some @{text "\<beta>"}-simplifications) |
592 the abstraction function |
593 the abstraction function |
593 |
594 |
594 @{text [display, indent=10] "(map (map id \<circ> Rep_fset) \<circ> Rep_fset) \<singlearr> Abs_fset \<circ> map id"} |
595 @{text [display, indent=10] "(map_list (map_list id \<circ> Rep_fset) \<circ> Rep_fset) \<singlearr> Abs_fset \<circ> map_list id"} |
595 |
596 |
596 \noindent |
597 \noindent |
597 In our implementation we further |
598 In our implementation we further |
598 simplify this function by rewriting with the usual laws about @{text |
599 simplify this function by rewriting with the usual laws about @{text |
599 "map"}s and @{text "id"}, namely @{term "map id = id"} and @{text "f \<circ> id = |
600 "map"}s and @{text "id"}, for example @{term "map_list id = id"} and @{text "f \<circ> id = |
600 id \<circ> f = f"}. This gives us the simpler abstraction function |
601 id \<circ> f = f"}. This gives us the simpler abstraction function |
601 |
602 |
602 @{text [display, indent=10] "(map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset"} |
603 @{text [display, indent=10] "(map_list Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset"} |
603 |
604 |
604 \noindent |
605 \noindent |
605 which we can use for defining @{term "fconcat"} as follows |
606 which we can use for defining @{term "fconcat"} as follows |
606 |
607 |
607 @{text [display, indent=10] "\<Union> \<equiv> ((map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset) flat"} |
608 @{text [display, indent=10] "\<Union> \<equiv> ((map_list Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset) flat"} |
608 |
609 |
609 \noindent |
610 \noindent |
610 Note that by using the operator @{text "\<singlearr>"} and special clauses |
611 Note that by using the operator @{text "\<singlearr>"} and special clauses |
611 for function types in \eqref{ABSREP}, we do not have to |
612 for function types in \eqref{ABSREP}, we do not have to |
612 distinguish between arguments and results, but can deal with them uniformly. |
613 distinguish between arguments and results, but can deal with them uniformly. |
684 \begin{tabular}{rcl} |
685 \begin{tabular}{rcl} |
685 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal types:}\\ |
686 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal types:}\\ |
686 @{text "REL (\<sigma>, \<sigma>)"} & $\dn$ & @{text "= :: \<sigma> \<Rightarrow> \<sigma> \<Rightarrow> bool"}\smallskip\\ |
687 @{text "REL (\<sigma>, \<sigma>)"} & $\dn$ & @{text "= :: \<sigma> \<Rightarrow> \<sigma> \<Rightarrow> bool"}\smallskip\\ |
687 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
688 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
688 @{text "REL (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "rel_\<kappa> (REL (\<sigma>s, \<tau>s))"}\smallskip\\ |
689 @{text "REL (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "rel_\<kappa> (REL (\<sigma>s, \<tau>s))"}\smallskip\\ |
689 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors:}\smallskip\\ |
690 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors with @{text "\<alpha>s |
|
691 \<kappa>\<^isub>q"} being the quotient of the raw type @{text "\<rho>s \<kappa>"}:}\smallskip\\ |
690 @{text "REL (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "rel_\<kappa>\<^isub>q (REL (\<sigma>s', \<tau>s))"}\\ |
692 @{text "REL (\<sigma>s \<kappa>, \<tau>s \<kappa>\<^isub>q)"} & $\dn$ & @{text "rel_\<kappa>\<^isub>q (REL (\<sigma>s', \<tau>s))"}\\ |
691 \end{tabular}\hfill\numbered{REL} |
693 \end{tabular}\hfill\numbered{REL} |
692 \end{center} |
694 \end{center} |
693 |
695 |
694 \noindent |
696 \noindent |
695 The @{text "\<sigma>s'"} in the last clause are calculated as in \eqref{ABSREP}: |
697 The @{text "\<sigma>s'"} in the last clause are calculated as in \eqref{ABSREP}: |
696 we know that type @{text "\<alpha>s \<kappa>\<^isub>q"} is the quotient of the raw type |
698 we know that type @{text "\<alpha>s \<kappa>\<^isub>q"} is the quotient of the raw type |
697 @{text "\<rho>s \<kappa>"}. The @{text "\<sigma>s'"} are determined by matching |
699 @{text "\<rho>s \<kappa>"}. The @{text "\<sigma>s'"} are the substitutions for @{text "\<alpha>s"} obtained by matching |
698 @{text "\<rho>s \<kappa>"} and @{text "\<sigma>s \<kappa>"}. |
700 @{text "\<rho>s \<kappa>"} and @{text "\<sigma>s \<kappa>"}. |
699 |
701 |
700 Let us return to the lifting procedure of theorems. Assume we have a theorem |
702 Let us return to the lifting procedure of theorems. Assume we have a theorem |
701 that contains the raw constant @{text "c\<^isub>r :: \<sigma>"} and which we want to |
703 that contains the raw constant @{text "c\<^isub>r :: \<sigma>"} and which we want to |
702 lift to a theorem where @{text "c\<^isub>r"} is replaced by the corresponding |
704 lift to a theorem where @{text "c\<^isub>r"} is replaced by the corresponding |
760 |
762 |
761 \noindent |
763 \noindent |
762 where the @{text "\<alpha>s"} stand for the type variables in the type of @{text "c\<^isub>r"}. |
764 where the @{text "\<alpha>s"} stand for the type variables in the type of @{text "c\<^isub>r"}. |
763 In case of @{text cons} (which has type @{text "\<alpha> \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list"}) we have |
765 In case of @{text cons} (which has type @{text "\<alpha> \<Rightarrow> \<alpha> list \<Rightarrow> \<alpha> list"}) we have |
764 |
766 |
765 @{text [display, indent=10] "(Rep ---> map Rep ---> map Abs) cons = cons"} |
767 @{text [display, indent=10] "(Rep ---> map_list Rep ---> map_list Abs) cons = cons"} |
766 |
768 |
767 \noindent |
769 \noindent |
768 under the assumption @{text "Quotient R Abs Rep"}. Interestingly, if we have |
770 under the assumption @{text "Quotient R Abs Rep"}. Interestingly, if we have |
769 an instance of @{text cons} where the type variable @{text \<alpha>} is instantiated |
771 an instance of @{text cons} where the type variable @{text \<alpha>} is instantiated |
770 with @{text "nat \<times> nat"} and we also quotient this type to yield integers, |
772 with @{text "nat \<times> nat"} and we also quotient this type to yield integers, |
790 %theorem which allows quotienting inside the container: |
792 %theorem which allows quotienting inside the container: |
791 % |
793 % |
792 %If @ {term R} is an equivalence relation and @ {term "Quotient R Abs Rep"} |
794 %If @ {term R} is an equivalence relation and @ {term "Quotient R Abs Rep"} |
793 %then |
795 %then |
794 % |
796 % |
795 %@ {text [display, indent=10] "Quotient (list_rel R \<circ>\<circ>\<circ> \<approx>\<^bsub>list\<^esub>) (abs_fset \<circ> map Abs) (map Rep o rep_fset)"} |
797 %@ {text [display, indent=10] "Quotient (list_rel R \<circ>\<circ>\<circ> \<approx>\<^bsub>list\<^esub>) (abs_fset \<circ> map_list Abs) (map_list Rep o rep_fset)"} |
796 %%% |
798 %%% |
797 %%%\noindent |
799 %%%\noindent |
798 %%%this theorem will then instantiate the quotients needed in the |
800 %%%this theorem will then instantiate the quotients needed in the |
799 %%%injection and cleaning proofs allowing the lifting procedure to |
801 %%%injection and cleaning proofs allowing the lifting procedure to |
800 %%%proceed in an unchanged way. |
802 %%%proceed in an unchanged way. |