308 by (rule subsetI, case_tac x, auto simp add: spair_eq_iff) |
308 by (rule subsetI, case_tac x, auto simp add: spair_eq_iff) |
309 thus "finite {x. sprod_map\<cdot>d1\<cdot>d2\<cdot>x = x}" |
309 thus "finite {x. sprod_map\<cdot>d1\<cdot>d2\<cdot>x = x}" |
310 by (rule finite_subset, simp add: d1.finite_fixes d2.finite_fixes) |
310 by (rule finite_subset, simp add: d1.finite_fixes d2.finite_fixes) |
311 qed |
311 qed |
312 |
312 |
313 subsection {* Strict product is a bifinite domain *} |
313 subsection {* Strict product is an SFP domain *} |
314 |
314 |
315 instantiation sprod :: (bifinite, bifinite) bifinite |
315 definition |
|
316 sprod_approx :: "nat \<Rightarrow> udom \<otimes> udom \<rightarrow> udom \<otimes> udom" |
|
317 where |
|
318 "sprod_approx = (\<lambda>i. sprod_map\<cdot>(udom_approx i)\<cdot>(udom_approx i))" |
|
319 |
|
320 lemma sprod_approx: "approx_chain sprod_approx" |
|
321 proof (rule approx_chain.intro) |
|
322 show "chain (\<lambda>i. sprod_approx i)" |
|
323 unfolding sprod_approx_def by simp |
|
324 show "(\<Squnion>i. sprod_approx i) = ID" |
|
325 unfolding sprod_approx_def |
|
326 by (simp add: lub_distribs sprod_map_ID) |
|
327 show "\<And>i. finite_deflation (sprod_approx i)" |
|
328 unfolding sprod_approx_def |
|
329 by (intro finite_deflation_sprod_map finite_deflation_udom_approx) |
|
330 qed |
|
331 |
|
332 definition sprod_sfp :: "sfp \<rightarrow> sfp \<rightarrow> sfp" |
|
333 where "sprod_sfp = sfp_fun2 sprod_approx sprod_map" |
|
334 |
|
335 lemma cast_sprod_sfp: |
|
336 "cast\<cdot>(sprod_sfp\<cdot>A\<cdot>B) = |
|
337 udom_emb sprod_approx oo |
|
338 sprod_map\<cdot>(cast\<cdot>A)\<cdot>(cast\<cdot>B) oo |
|
339 udom_prj sprod_approx" |
|
340 unfolding sprod_sfp_def |
|
341 apply (rule cast_sfp_fun2 [OF sprod_approx]) |
|
342 apply (erule (1) finite_deflation_sprod_map) |
|
343 done |
|
344 |
|
345 instantiation sprod :: (sfp, sfp) sfp |
316 begin |
346 begin |
317 |
347 |
318 definition |
348 definition |
319 approx_sprod_def: |
349 "emb = udom_emb sprod_approx oo sprod_map\<cdot>emb\<cdot>emb" |
320 "approx = (\<lambda>n. sprod_map\<cdot>(approx n)\<cdot>(approx n))" |
350 |
|
351 definition |
|
352 "prj = sprod_map\<cdot>prj\<cdot>prj oo udom_prj sprod_approx" |
|
353 |
|
354 definition |
|
355 "sfp (t::('a \<otimes> 'b) itself) = sprod_sfp\<cdot>SFP('a)\<cdot>SFP('b)" |
321 |
356 |
322 instance proof |
357 instance proof |
323 fix i :: nat and x :: "'a \<otimes> 'b" |
358 show "ep_pair emb (prj :: udom \<rightarrow> 'a \<otimes> 'b)" |
324 show "chain (approx :: nat \<Rightarrow> 'a \<otimes> 'b \<rightarrow> 'a \<otimes> 'b)" |
359 unfolding emb_sprod_def prj_sprod_def |
325 unfolding approx_sprod_def by simp |
360 using ep_pair_udom [OF sprod_approx] |
326 show "(\<Squnion>i. approx i\<cdot>x) = x" |
361 by (intro ep_pair_comp ep_pair_sprod_map ep_pair_emb_prj) |
327 unfolding approx_sprod_def sprod_map_def |
362 next |
328 by (simp add: lub_distribs eta_cfun) |
363 show "cast\<cdot>SFP('a \<otimes> 'b) = emb oo (prj :: udom \<rightarrow> 'a \<otimes> 'b)" |
329 show "approx i\<cdot>(approx i\<cdot>x) = approx i\<cdot>x" |
364 unfolding emb_sprod_def prj_sprod_def sfp_sprod_def cast_sprod_sfp |
330 unfolding approx_sprod_def sprod_map_def |
365 by (simp add: cast_SFP oo_def expand_cfun_eq sprod_map_map) |
331 by (simp add: ssplit_def strictify_conv_if) |
|
332 show "finite {x::'a \<otimes> 'b. approx i\<cdot>x = x}" |
|
333 unfolding approx_sprod_def |
|
334 by (intro finite_deflation.finite_fixes |
|
335 finite_deflation_sprod_map |
|
336 finite_deflation_approx) |
|
337 qed |
366 qed |
338 |
367 |
339 end |
368 end |
340 |
369 |
341 lemma approx_spair [simp]: |
370 text {* SFP of type constructor = type combinator *} |
342 "approx i\<cdot>(:x, y:) = (:approx i\<cdot>x, approx i\<cdot>y:)" |
371 |
343 unfolding approx_sprod_def sprod_map_def |
372 lemma SFP_sprod: "SFP('a::sfp \<otimes> 'b::sfp) = sprod_sfp\<cdot>SFP('a)\<cdot>SFP('b)" |
344 by (simp add: ssplit_def strictify_conv_if) |
373 by (rule sfp_sprod_def) |
345 |
374 |
346 end |
375 end |