122 |
122 |
123 text %quoteme {*@{code_stmts bexp (Haskell)}*} |
123 text %quoteme {*@{code_stmts bexp (Haskell)}*} |
124 |
124 |
125 text {* |
125 text {* |
126 \noindent An inspection reveals that the equations stemming from the |
126 \noindent An inspection reveals that the equations stemming from the |
127 @{text primrec} statement within instantiation of class |
127 @{command primrec} statement within instantiation of class |
128 @{class semigroup} with type @{typ nat} are mapped to a separate |
128 @{class semigroup} with type @{typ nat} are mapped to a separate |
129 function declaration @{text mult_nat} which in turn is used |
129 function declaration @{verbatim mult_nat} which in turn is used |
130 to provide the right hand side for the @{text "instance Semigroup Nat"} |
130 to provide the right hand side for the @{verbatim "instance Semigroup Nat"}. |
131 \fixme[courier fuer code text, isastyle fuer class]. This perfectly |
131 This perfectly |
132 agrees with the restriction that @{text inst} statements may |
132 agrees with the restriction that @{text inst} statements may |
133 only contain one single equation for each class class parameter |
133 only contain one single equation for each class class parameter |
134 The @{text instantiation} mechanism manages that for each |
134 The @{command instantiation} mechanism manages that for each |
135 overloaded constant @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} |
135 overloaded constant @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} |
136 a \emph{shadow constant} @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} is |
136 a \emph{shadow constant} @{text "f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"} is |
137 declared satisfying @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>] \<equiv> f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}. |
137 declared satisfying @{text "f [\<kappa> \<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>] \<equiv> f\<^isub>\<kappa> [\<^bvec>\<alpha>\<Colon>s\<^isub>k\<^evec>]"}. |
138 this equation is indeed the one used for the statement; |
138 this equation is indeed the one used for the statement; |
139 using it as a rewrite rule, defining equations for |
139 using it as a rewrite rule, defining equations for |
342 then collect_duplicates xs ys zs |
342 then collect_duplicates xs ys zs |
343 else collect_duplicates xs (z#ys) zs |
343 else collect_duplicates xs (z#ys) zs |
344 else collect_duplicates (z#xs) (z#ys) zs)" |
344 else collect_duplicates (z#xs) (z#ys) zs)" |
345 |
345 |
346 text {* |
346 text {* |
347 The membership test during preprocessing is rewritten, |
347 \noindent The membership test during preprocessing is rewritten, |
348 resulting in @{const List.member}, which itself |
348 resulting in @{const List.member}, which itself |
349 performs an explicit equality check. |
349 performs an explicit equality check. |
350 *} |
350 *} |
351 |
351 |
352 text %quoteme {*@{code_stmts collect_duplicates (SML)}*} |
352 text %quoteme {*@{code_stmts collect_duplicates (SML)}*} |
366 enters the stage when definitions of overloaded constants |
366 enters the stage when definitions of overloaded constants |
367 are dependent on operational equality. For example, let |
367 are dependent on operational equality. For example, let |
368 us define a lexicographic ordering on tuples: |
368 us define a lexicographic ordering on tuples: |
369 *} |
369 *} |
370 |
370 |
371 instantiation * :: (ord, ord) ord |
371 instantiation %quoteme * :: (ord, ord) ord |
372 begin |
372 begin |
373 |
373 |
374 definition |
374 definition %quoteme [code func del]: |
375 [code func del]: "p1 < p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in |
375 "p1 < p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 < y2))" |
376 x1 < x2 \<or> (x1 = x2 \<and> y1 < y2))" |
376 |
377 |
377 definition %quoteme [code func del]: |
378 definition |
378 "p1 \<le> p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2))" |
379 [code func del]: "p1 \<le> p2 \<longleftrightarrow> (let (x1, y1) = p1; (x2, y2) = p2 in |
379 |
380 x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2))" |
380 instance %quoteme .. |
381 |
381 |
382 instance .. |
382 end %quoteme |
383 |
383 |
384 end |
384 lemma %quoteme ord_prod [code func]: |
385 |
|
386 lemma ord_prod [code func(*<*), code func del(*>*)]: |
|
387 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
385 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 < y2)" |
388 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)" |
386 "(x1 \<Colon> 'a\<Colon>ord, y1 \<Colon> 'b\<Colon>ord) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> (x1 = x2 \<and> y1 \<le> y2)" |
389 unfolding less_prod_def less_eq_prod_def by simp_all |
387 unfolding less_prod_def less_eq_prod_def by simp_all |
390 |
388 |
391 text {* |
389 text {* |
392 Then code generation will fail. Why? The definition |
390 \noindent Then code generation will fail. Why? The definition |
393 of @{term "op \<le>"} depends on equality on both arguments, |
391 of @{term "op \<le>"} depends on equality on both arguments, |
394 which are polymorphic and impose an additional @{class eq} |
392 which are polymorphic and impose an additional @{class eq} |
395 class constraint, thus violating the type discipline |
393 class constraint, which the preprocessort does not propagate for technical |
396 for class operations. |
394 reasons. |
397 |
395 |
398 The solution is to add @{class eq} explicitly to the first sort arguments in the |
396 The solution is to add @{class eq} explicitly to the first sort arguments in the |
399 code theorems: |
397 code theorems: |
400 *} |
398 *} |
401 |
399 |
411 *} |
409 *} |
412 |
410 |
413 text %quoteme {*@{code_stmts "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>ord \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" (SML)}*} |
411 text %quoteme {*@{code_stmts "op \<le> \<Colon> 'a\<Colon>{eq, ord} \<times> 'b\<Colon>ord \<Rightarrow> 'a \<times> 'b \<Rightarrow> bool" (SML)}*} |
414 |
412 |
415 text {* |
413 text {* |
416 In general, code theorems for overloaded constants may have more |
|
417 restrictive sort constraints than the underlying instance relation |
|
418 between class and type constructor as long as the whole system of |
|
419 constraints is coregular; code theorems violating coregularity |
|
420 are rejected immediately. Consequently, it might be necessary |
|
421 to delete disturbing theorems in the code theorem table, |
|
422 as we have done here with the original definitions @{fact less_prod_def} |
|
423 and @{fact less_eq_prod_def}. |
|
424 |
|
425 In some cases, the automatically derived defining equations |
414 In some cases, the automatically derived defining equations |
426 for equality on a particular type may not be appropriate. |
415 for equality on a particular type may not be appropriate. |
427 As example, watch the following datatype representing |
416 As example, watch the following datatype representing |
428 monomorphic parametric types (where type constructors |
417 monomorphic parametric types (where type constructors |
429 are referred to by natural numbers): |
418 are referred to by natural numbers): |
440 Then code generation for SML would fail with a message |
429 Then code generation for SML would fail with a message |
441 that the generated code contains illegal mutual dependencies: |
430 that the generated code contains illegal mutual dependencies: |
442 the theorem @{thm monotype_eq [no_vars]} already requires the |
431 the theorem @{thm monotype_eq [no_vars]} already requires the |
443 instance @{text "monotype \<Colon> eq"}, which itself requires |
432 instance @{text "monotype \<Colon> eq"}, which itself requires |
444 @{thm monotype_eq [no_vars]}; Haskell has no problem with mutually |
433 @{thm monotype_eq [no_vars]}; Haskell has no problem with mutually |
445 recursive @{text instance} and @{text function} definitions, |
434 recursive @{text inst} and @{text fun} definitions, |
446 but the SML serializer does not support this. |
435 but the SML serializer does not support this. |
447 |
436 |
448 In such cases, you have to provide you own equality equations |
437 In such cases, you have to provide you own equality equations |
449 involving auxiliary constants. In our case, |
438 involving auxiliary constants. In our case, |
450 @{const [show_types] list_all2} can do the job: |
439 @{const [show_types] list_all2} can do the job: |