146 |
148 |
147 \end{tikzpicture} |
149 \end{tikzpicture} |
148 \end{center} |
150 \end{center} |
149 |
151 |
150 \noindent |
152 \noindent |
151 The starting point is an existing type, often referred to as the \emph{raw |
153 The starting point is an existing type, to which we often refer as the |
152 type}, over which an equivalence relation given by the user is defined. With |
154 \emph{raw type}, over which an equivalence relation given by the user is |
153 this input the package introduces a new type, to which we refer as the |
155 defined. With this input the package introduces a new type, to which we |
154 \emph{quotient type}. This type comes with an \emph{abstraction} and a |
156 refer as the \emph{quotient type}. This type comes with an |
155 \emph{representation} function, written @{text Abs} and @{text |
157 \emph{abstraction} and a \emph{representation} function, written @{text Abs} |
156 Rep}.\footnote{Actually slightly more basic functions are given; the @{text Abs} |
158 and @{text Rep}.\footnote{Actually slightly more basic functions are given; |
157 and @{text Rep} need to be derived from them. We will show the details |
159 the functions @{text Abs} and @{text Rep} need to be derived from them. We |
158 later. } These functions relate elements in the existing type to ones in the |
160 will show the details later. } These functions relate elements in the |
159 new type and vice versa; they can be uniquely identified by their type. For |
161 existing type to ones in the new type and vice versa; they can be uniquely |
160 example for the integer quotient construction the types of @{text Abs} and |
162 identified by their type. For example for the integer quotient construction |
161 @{text Rep} are |
163 the types of @{text Abs} and @{text Rep} are |
|
164 |
162 |
165 |
163 \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%% |
166 \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%% |
164 @{text "Abs :: nat \<times> nat \<Rightarrow> int"}\hspace{10mm}@{text "Rep :: int \<Rightarrow> nat \<times> nat"} |
167 @{text "Abs :: nat \<times> nat \<Rightarrow> int"}\hspace{10mm}@{text "Rep :: int \<Rightarrow> nat \<times> nat"} |
165 \end{isabelle} |
168 \end{isabelle} |
166 |
169 |
167 \noindent |
170 \noindent |
168 However we often leave this typing information implicit for better |
171 We therefore often write @{text Abs_int} and @{text Rep_int} if the |
169 readability, but sometimes write @{text Abs_int} and @{text Rep_int} if the |
172 typing information is important. |
170 typing information is important. Every abstraction and representation |
173 |
171 function stands for an isomorphism between the non-empty subset and elements |
174 Every abstraction and representation function stands for an isomorphism |
172 in the new type. They are necessary for making definitions involving the new |
175 between the non-empty subset and elements in the new type. They are |
173 type. For example @{text "0"} and @{text "1"} of type @{typ int} can be |
176 necessary for making definitions involving the new type. For example @{text |
174 defined as |
177 "0"} and @{text "1"} of type @{typ int} can be defined as |
175 |
178 |
176 \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%% |
179 |
177 @{text "0 \<equiv> Abs (0, 0)"}\hspace{10mm}@{text "1 \<equiv> Abs (1, 0)"} |
180 \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%% |
|
181 @{text "0 \<equiv> Abs_int (0, 0)"}\hspace{10mm}@{text "1 \<equiv> Abs_int (1, 0)"} |
178 \end{isabelle} |
182 \end{isabelle} |
179 |
183 |
180 \noindent |
184 \noindent |
181 Slightly more complicated is the definition of @{text "add"} having type |
185 Slightly more complicated is the definition of @{text "add"} having type |
182 @{typ "int \<Rightarrow> int \<Rightarrow> int"}. Its definition is as follows |
186 @{typ "int \<Rightarrow> int \<Rightarrow> int"}. Its definition is as follows |
183 |
187 |
184 @{text [display, indent=10] "add n m \<equiv> Abs (add_pair (Rep n) (Rep m))"} |
188 @{text [display, indent=10] "add n m \<equiv> Abs_int (add_pair (Rep_int n) (Rep_int m))"} |
185 |
189 |
186 \noindent |
190 \noindent |
187 where we take the representation of the arguments @{text n} and @{text m}, |
191 where we take the representation of the arguments @{text n} and @{text m}, |
188 add them according to the function @{text "add_pair"} and then take the |
192 add them according to the function @{text "add_pair"} and then take the |
189 abstraction of the result. This is all straightforward and the existing |
193 abstraction of the result. This is all straightforward and the existing |
400 \end{tabular} |
405 \end{tabular} |
401 \end{isabelle} |
406 \end{isabelle} |
402 |
407 |
403 \noindent |
408 \noindent |
404 The first one declares zero for integers and the second the operator for |
409 The first one declares zero for integers and the second the operator for |
405 building unions of finite sets. The problem for us is that from such |
410 building unions of finite sets. |
406 declarations we need to derive proper definitions using the @{text "Abs"} |
411 |
407 and @{text "Rep"} functions for the quotient types involved. The data we |
412 The problem for us is that from such declarations we need to derive proper |
408 rely on is the given quotient type @{text "\<tau>"} and the raw type @{text "\<sigma>"}. |
413 definitions using the @{text "Abs"} and @{text "Rep"} functions for the |
409 They allow us to define aggregate abstraction and representation functions |
414 quotient types involved. The data we rely on is the given quotient type |
410 using the functions @{text "ABS (\<sigma>, \<tau>)"} and @{text "REP (\<sigma>, \<tau>)"} whose |
415 @{text "\<tau>"} and the raw type @{text "\<sigma>"}. They allow us to define aggregate |
411 clauses are given below. The idea behind them is to recursively descend into |
416 abstraction and representation functions using the functions @{text "ABS (\<sigma>, |
412 both types and generate the appropriate @{text "Abs"} and @{text "Rep"} |
417 \<tau>)"} and @{text "REP (\<sigma>, \<tau>)"} whose clauses are given below. The idea behind |
413 in places where the types differ. Therefore we returning just the identity |
418 them is to recursively descend into types @{text \<sigma>} and @{text \<tau>}, and generate the appropriate |
414 whenever the types are equal. |
419 @{text "Abs"} and @{text "Rep"} in places where the types differ. Therefore |
|
420 we returning just the identity whenever the types are equal. All clauses |
|
421 are as follows: |
415 |
422 |
416 \begin{center} |
423 \begin{center} |
417 \begin{longtable}{rcl} |
424 \begin{tabular}{rcl} |
418 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal types:}\\ |
425 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal types:}\\ |
419 @{text "ABS (\<sigma>, \<sigma>)"} & $\dn$ & @{text "id"}\\ |
426 @{text "ABS (\<sigma>, \<sigma>)"} & $\dn$ & @{text "id :: \<sigma> \<Rightarrow> \<sigma>"}\\ |
420 @{text "REP (\<sigma>, \<sigma>)"} & $\dn$ & @{text "id"}\smallskip\\ |
427 @{text "REP (\<sigma>, \<sigma>)"} & $\dn$ & @{text "id :: \<sigma> \<Rightarrow> \<sigma>"}\smallskip\\ |
421 \multicolumn{3}{@ {\hspace{-4mm}}l}{function types:}\\ |
428 \multicolumn{3}{@ {\hspace{-4mm}}l}{function types:}\\ |
422 @{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)"}\\ |
429 @{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)"}\\ |
423 @{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\\ |
430 @{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\\ |
424 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
431 \multicolumn{3}{@ {\hspace{-4mm}}l}{equal type constructors:}\\ |
425 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (ABS (\<sigma>s, \<tau>s))"}\\ |
432 @{text "ABS (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (ABS (\<sigma>s, \<tau>s))"}\\ |
426 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (REP (\<sigma>s, \<tau>s))"}\smallskip\\ |
433 @{text "REP (\<sigma>s \<kappa>, \<tau>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (REP (\<sigma>s, \<tau>s))"}\smallskip\\ |
427 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors:}\\ |
434 \multicolumn{3}{@ {\hspace{-4mm}}l}{unequal type constructors:}\\ |
428 @{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')))"}\\ |
435 @{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)))"}\\ |
429 @{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"} |
436 @{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"} |
430 \end{longtable} |
437 \end{tabular} |
431 \end{center} |
438 \end{center} |
432 % |
439 % |
433 \noindent |
440 \noindent |
434 where in the last two clauses we have that the quotient type @{text "\<alpha>s |
441 where in the last two clauses we have that the quotient type @{text "\<alpha>s |
435 \<kappa>\<^isub>q"} is a quotient of the raw type @{text "\<rho>s \<kappa>"} (for example |
442 \<kappa>\<^isub>q"} is the quotient of the raw type @{text "\<rho>s \<kappa>"} (for example |
436 @{text "int"} and @{text "nat \<times> nat"}, or @{text "\<alpha> fset"} and @{text "\<alpha> |
443 @{text "int"} and @{text "nat \<times> nat"}, or @{text "\<alpha> fset"} and @{text "\<alpha> |
437 list"}). The quotient construction ensures that the type variables in @{text |
444 list"}). The quotient construction ensures that the type variables in @{text |
438 "\<rho>s"} must be amongst the @{text "\<alpha>s"}. The @{text "\<sigma>s'"} are given by the |
445 "\<rho>s"} must be amongst the @{text "\<alpha>s"}. The @{text "\<sigma>s'"} are given by the |
439 matchers for the @{text "\<alpha>s"} when matching @{text "\<sigma>s \<kappa>\<^isub>q"} against |
446 matchers for the @{text "\<alpha>s"} when matching @{text "\<rho>s \<kappa>"} against |
440 @{text "\<alpha>s \<kappa>\<^isub>q"}; similarly the @{text "\<tau>s'"} are given by the same |
447 @{text "\<sigma>s \<kappa>"}. The |
441 type-variables when matching @{text "\<tau>s \<kappa>"} against @{text "\<rho>s \<kappa>"}. The |
|
442 function @{text "MAP"} calculates an \emph{aggregate map-function} for a raw |
448 function @{text "MAP"} calculates an \emph{aggregate map-function} for a raw |
443 type as follows: |
449 type as follows: |
444 % |
450 % |
445 \begin{center} |
451 \begin{center} |
446 \begin{longtable}{rcl} |
452 \begin{tabular}{rcl} |
447 @{text "MAP' (\<alpha>)"} & $\dn$ & @{text "a\<^sup>\<alpha>"}\\ |
453 @{text "MAP' (\<alpha>)"} & $\dn$ & @{text "a\<^sup>\<alpha>"}\\ |
448 @{text "MAP' (\<kappa>)"} & $\dn$ & @{text "id"}\\ |
454 @{text "MAP' (\<kappa>)"} & $\dn$ & @{text "id :: \<kappa> \<Rightarrow> \<kappa>"}\\ |
449 @{text "MAP' (\<sigma>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (MAP'(\<sigma>s))"}\smallskip\\ |
455 @{text "MAP' (\<sigma>s \<kappa>)"} & $\dn$ & @{text "map_\<kappa> (MAP'(\<sigma>s))"}\smallskip\\ |
450 @{text "MAP (\<sigma>)"} & $\dn$ & @{text "\<lambda>as. MAP'(\<sigma>)"} |
456 @{text "MAP (\<sigma>)"} & $\dn$ & @{text "\<lambda>as. MAP'(\<sigma>)"} |
451 \end{longtable} |
457 \end{tabular} |
452 \end{center} |
458 \end{center} |
453 % |
459 % |
454 \noindent |
460 \noindent |
455 In this definition we abuse the fact that we can interpret type-variables @{text \<alpha>} as |
461 In this definition we abuse the fact that we can interpret type-variables @{text \<alpha>} as |
456 term variables @{text a}, and in the last clause build an abstraction over all |
462 term variables @{text a}. In the last clause we build an abstraction over all |
457 term-variables inside the aggregate map-function generated by @{text "MAP'"}. |
463 term-variables inside the aggregate map-function generated by the auxiliary function |
458 This aggregate map-function is necessary if we build quotients, say @{text "(\<alpha>, \<beta>) \<kappa>\<^isub>q"}, |
464 @{text "MAP'"}. |
459 out of compound raw types, say @{text "(\<alpha> list) \<times> \<beta>"}. In this case @{text MAP} |
465 The need of aggregate map-functions can be appreciated if we build quotients, |
460 generates the aggregate map-function: |
466 say @{text "(\<alpha>, \<beta>) \<kappa>\<^isub>q"}, out of compound raw types of the form @{text "(\<alpha> list) \<times> \<beta>"}. |
|
467 In this case @{text MAP} generates the aggregate map-function: |
461 |
468 |
462 @{text [display, indent=10] "\<lambda>a b. map_prod (map a) b"} |
469 @{text [display, indent=10] "\<lambda>a b. map_prod (map a) b"} |
463 |
470 |
464 \noindent |
471 \noindent |
465 Returning to our example about @{term "concat"} and @{term "fconcat"} which have the |
472 which we need to define the aggregate abstraction and representation functions. |
466 types @{text "(\<alpha> list) list \<Rightarrow> \<alpha> list"} and @{text "(\<alpha> fset) fset \<Rightarrow> \<alpha> fset"}. Feeding this |
473 |
467 into @{text ABS} gives us the abstraction function: |
474 To se how these definitions pan out in practise, let us return to our |
|
475 example about @{term "concat"} and @{term "fconcat"}, where we have types |
|
476 @{text "(\<alpha> list) list \<Rightarrow> \<alpha> list"} and @{text "(\<alpha> fset) fset \<Rightarrow> \<alpha> |
|
477 fset"}. Feeding them into @{text ABS} gives us the abstraction function |
468 |
478 |
469 @{text [display, indent=10] "(map (map id \<circ> Rep_fset) \<circ> Rep_fset) \<singlearr> Abs_fset \<circ> map id"} |
479 @{text [display, indent=10] "(map (map id \<circ> Rep_fset) \<circ> Rep_fset) \<singlearr> Abs_fset \<circ> map id"} |
470 |
480 |
471 \noindent |
481 \noindent |
472 where we already performed some @{text "\<beta>"}-simplifications. In our |
482 after some @{text "\<beta>"}-simplifications. In our implementation we further |
473 implementation we further simplify this by noticing the usual laws about |
483 simplify this abstraction function employing the usual laws about @{text |
474 @{text "map"}s and @{text "id"}, namely @{term "map id = id"} and @{text "f |
484 "map"}s and @{text "id"}, namely @{term "map id = id"} and @{text "f \<circ> id = |
475 \<circ> id = id \<circ> f = f"}. This gives us the simplified abstraction function |
485 id \<circ> f = f"}. This gives us the abstraction function |
476 |
486 |
477 @{text [display, indent=10] "(map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset"} |
487 @{text [display, indent=10] "(map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset"} |
478 |
488 |
479 \noindent |
489 \noindent |
480 which we can use for defining @{term "fconcat"} as follows |
490 which we can use for defining @{term "fconcat"} as follows |
481 |
491 |
482 @{text [display, indent=10] "\<Union> \<equiv> ((map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset) flat"} |
492 @{text [display, indent=10] "\<Union> \<equiv> ((map Rep_fset \<circ> Rep_fset) \<singlearr> Abs_fset) flat"} |
483 |
493 |
484 \noindent |
494 \noindent |
485 Note that by using the operator @{text "\<singlearr>"} we do not have to |
495 Note that by using the operator @{text "\<singlearr>"} we do not have to |
486 distinguish between arguments and results: teh representation and abstraction |
496 distinguish between arguments and results: the representation and abstraction |
487 functions are just inverses which we can combine using @{text "\<singlearr>"}. |
497 functions are just inverses of each other, which we can combine using |
488 So all our definitions are of the general form |
498 @{text "\<singlearr>"} to deal uniformly with arguments of functions and |
|
499 their result. As a result, all definitions in the quotient package |
|
500 are of the general form |
489 |
501 |
490 @{text [display, indent=10] "c \<equiv> ABS (\<sigma>, \<tau>) t"} |
502 @{text [display, indent=10] "c \<equiv> ABS (\<sigma>, \<tau>) t"} |
491 |
503 |
492 \noindent |
504 \noindent |
493 where @{text \<sigma>} is the type of @{text "t"} and @{text "\<tau>"} the type of the |
505 where @{text \<sigma>} is the type of the definiens @{text "t"} and @{text "\<tau>"} the |
494 newly defined quotient constant @{text "c"}. To ensure we obtained a correct |
506 type of the defined quotient constant @{text "c"}. To ensure we |
495 definition, we can prove: |
507 obtained a correct definition, we can prove: |
496 |
508 |
497 \begin{lemma} |
509 \begin{lemma} |
498 If @{text "ABS (\<sigma>, \<tau>)"} returns some abstraction function @{text "Abs"} |
510 If @{text "ABS (\<sigma>, \<tau>)"} returns some abstraction function @{text "Abs"} |
499 and @{text "REP (\<sigma>, \<tau>)"} some representation function @{text "Rep"}, |
511 and @{text "REP (\<sigma>, \<tau>)"} some representation function @{text "Rep"}, |
500 then @{text "Abs"} is of type @{text "\<sigma> \<Rightarrow> \<tau>"} and @{text "Rep"} of type |
512 then @{text "Abs"} is of type @{text "\<sigma> \<Rightarrow> \<tau>"} and @{text "Rep"} of type |
501 @{text "\<tau> \<Rightarrow> \<sigma>"}. |
513 @{text "\<tau> \<Rightarrow> \<sigma>"}. |
502 \end{lemma} |
514 \end{lemma} |
503 |
515 |
504 \begin{proof} |
516 \begin{proof} |
505 By induction of the definitions of @{text "ABS"}, @{text "REP"} and @{text "MAP"}. |
517 By induction and analysing the definitions of @{text "ABS"}, @{text "REP"} |
|
518 and @{text "MAP"}. The cases of equal and function types are straightforward |
|
519 (the latter follows from @{text "\<singlearr>"} having the type |
|
520 @{text "(\<alpha> \<Rightarrow> \<beta>) \<Rightarrow> (\<gamma> \<Rightarrow> \<delta>) \<Rightarrow> (\<beta> \<Rightarrow> \<gamma>) \<Rightarrow> (\<alpha> \<Rightarrow> \<delta>)"}). The case of equal |
|
521 type constructors follows by observing that a map-function after applying |
|
522 the functions @{text "ABS (\<sigma>s, \<tau>s)"} produce a term of type @{text "\<sigma>s \<kappa> \<Rightarrow> \<tau>s \<kappa>"}. |
|
523 The interesting case is the one with unequal type constructors. Since we know the |
|
524 quotient is between @{text "\<alpha>s \<kappa>\<^isub>q"} and @{text "\<rho>s \<kappa>"}, we have that @{text "Abs_\<kappa>\<^isub>q"} |
|
525 is of type @{text "\<rho>s \<kappa> \<Rightarrow> \<alpha>s \<kappa>\<^isub>q"}, that can be more specialised to @{text "\<rho>s[\<tau>s] \<kappa> \<Rightarrow> \<tau>s \<kappa>\<^isub>q"} |
|
526 where the type variables @{text "\<alpha>s"} are instantiated with @{text "\<tau>s"}. The |
|
527 complete type can be calculated by observing that @{text "MAP (\<rho>s \<kappa>)"} after applying |
|
528 the functions @{text "ABS (\<sigma>s', \<tau>s)"} to it, returns a term of type |
|
529 @{text "\<rho>s[\<sigma>s'] \<kappa> \<Rightarrow> \<rho>s[\<tau>s] \<kappa>"}. This type is equivalent to @{text "\<sigma>s \<kappa> \<Rightarrow> \<rho>s[\<tau>s] \<kappa>"} |
|
530 as desired.\qed |
506 \end{proof} |
531 \end{proof} |
507 |
532 |
508 \noindent |
533 \noindent |
509 This lemma fails for the abstraction and representation functions used in, |
534 The reader should note that this lemma fails for the abstraction and representation |
510 for example, Homeier's quotient package. |
535 functions used, for example, in Homeier's quotient package. |
511 *} |
536 *} |
512 |
537 |
513 subsection {* Respectfulness *} |
538 section {* Respectfulness and Preservation *} |
514 |
539 |
515 text {* |
540 text {* |
516 |
541 Before we can lift theorems involving the raw types to theorems over |
517 A respectfulness lemma for a constant states that the equivalence |
542 quotient types, we have to impose some restrictions. The reason is that not |
|
543 all theorems can be lifted. Homeier formulates these restrictions in terms |
|
544 of \emph{respectfullness} and \emph{preservation} of constants occuring in |
|
545 theorems. |
|
546 |
|
547 The respectfulness property for a constant states that it essentially |
|
548 respects the equivalence relation involved in the quotient. An example |
|
549 is the function returning bound variables of a lambda-term (see \eqref{lambda}) |
|
550 and @{text "\<alpha>"}-equivalence. It will turn out that this function is not |
|
551 respectful. |
|
552 |
|
553 To state the respectfulness property we have to define \emph{aggregate equivalence |
|
554 relations}. |
|
555 |
|
556 @{text [display] "GIVE DEFINITION HERE"} |
|
557 |
518 class returned by this constant depends only on the equivalence |
558 class returned by this constant depends only on the equivalence |
519 classes of the arguments applied to the constant. To automatically |
559 classes of the arguments applied to the constant. To automatically |
520 lift a theorem that talks about a raw constant, to a theorem about |
560 lift a theorem that talks about a raw constant, to a theorem about |
521 the quotient type a respectfulness theorem is required. |
561 the quotient type a respectfulness theorem is required. |
522 |
562 |
523 A respectfulness condition for a constant can be expressed in |
563 A respectfulness condition for a constant can be expressed in |
524 terms of an aggregate relation between the constant and itself, |
564 terms of an aggregate relation between the constant and itself, |
525 for example the respectfullness for @{term "append"} |
565 for example the respectfullness for @{text "append"} |
526 can be stated as: |
566 can be stated as: |
527 |
567 |
528 @{thm [display, indent=10] append_rsp[no_vars]} |
568 @{text [display, indent=10] "(R \<doublearr> R \<doublearr> R) append append"} |
529 |
569 |
530 \noindent |
570 \noindent |
531 Which after unfolding the definition of @{term "op ===>"} is equivalent to: |
571 Which after unfolding the definition of @{term "op ===>"} is equivalent to: |
532 |
572 |
533 @{thm [display, indent=10] append_rsp_unfolded[no_vars]} |
573 @{thm [display, indent=10] append_rsp_unfolded[no_vars]} |