296 where EqNIL: "(NIL, NIL) \<in> EqLList r" |
296 where EqNIL: "(NIL, NIL) \<in> EqLList r" |
297 | EqCONS: "(a, b) \<in> r \<Longrightarrow> (M, N) \<in> EqLList r \<Longrightarrow> |
297 | EqCONS: "(a, b) \<in> r \<Longrightarrow> (M, N) \<in> EqLList r \<Longrightarrow> |
298 (CONS a M, CONS b N) \<in> EqLList r" |
298 (CONS a M, CONS b N) \<in> EqLList r" |
299 |
299 |
300 lemma EqLList_unfold: |
300 lemma EqLList_unfold: |
301 "EqLList r = dsum (diag {Datatype.Numb 0}) (dprod r (EqLList r))" |
301 "EqLList r = dsum (Id_on {Datatype.Numb 0}) (dprod r (EqLList r))" |
302 by (fast intro!: EqLList.intros [unfolded NIL_def CONS_def] |
302 by (fast intro!: EqLList.intros [unfolded NIL_def CONS_def] |
303 elim: EqLList.cases [unfolded NIL_def CONS_def]) |
303 elim: EqLList.cases [unfolded NIL_def CONS_def]) |
304 |
304 |
305 lemma EqLList_implies_ntrunc_equality: |
305 lemma EqLList_implies_ntrunc_equality: |
306 "(M, N) \<in> EqLList (diag A) \<Longrightarrow> ntrunc k M = ntrunc k N" |
306 "(M, N) \<in> EqLList (Id_on A) \<Longrightarrow> ntrunc k M = ntrunc k N" |
307 apply (induct k arbitrary: M N rule: nat_less_induct) |
307 apply (induct k arbitrary: M N rule: nat_less_induct) |
308 apply (erule EqLList.cases) |
308 apply (erule EqLList.cases) |
309 apply (safe del: equalityI) |
309 apply (safe del: equalityI) |
310 apply (case_tac n) |
310 apply (case_tac n) |
311 apply simp |
311 apply simp |
312 apply (rename_tac n') |
312 apply (rename_tac n') |
313 apply (case_tac n') |
313 apply (case_tac n') |
314 apply (simp_all add: CONS_def less_Suc_eq) |
314 apply (simp_all add: CONS_def less_Suc_eq) |
315 done |
315 done |
316 |
316 |
317 lemma Domain_EqLList: "Domain (EqLList (diag A)) \<subseteq> LList A" |
317 lemma Domain_EqLList: "Domain (EqLList (Id_on A)) \<subseteq> LList A" |
318 apply (rule subsetI) |
318 apply (rule subsetI) |
319 apply (erule LList.coinduct) |
319 apply (erule LList.coinduct) |
320 apply (subst (asm) EqLList_unfold) |
320 apply (subst (asm) EqLList_unfold) |
321 apply (auto simp add: NIL_def CONS_def) |
321 apply (auto simp add: NIL_def CONS_def) |
322 done |
322 done |
323 |
323 |
324 lemma EqLList_diag: "EqLList (diag A) = diag (LList A)" |
324 lemma EqLList_Id_on: "EqLList (Id_on A) = Id_on (LList A)" |
325 (is "?lhs = ?rhs") |
325 (is "?lhs = ?rhs") |
326 proof |
326 proof |
327 show "?lhs \<subseteq> ?rhs" |
327 show "?lhs \<subseteq> ?rhs" |
328 apply (rule subsetI) |
328 apply (rule subsetI) |
329 apply (rule_tac p = x in PairE) |
329 apply (rule_tac p = x in PairE) |
330 apply clarify |
330 apply clarify |
331 apply (rule diag_eqI) |
331 apply (rule Id_on_eqI) |
332 apply (rule EqLList_implies_ntrunc_equality [THEN ntrunc_equality], |
332 apply (rule EqLList_implies_ntrunc_equality [THEN ntrunc_equality], |
333 assumption) |
333 assumption) |
334 apply (erule DomainI [THEN Domain_EqLList [THEN subsetD]]) |
334 apply (erule DomainI [THEN Domain_EqLList [THEN subsetD]]) |
335 done |
335 done |
336 { |
336 { |
337 fix M N assume "(M, N) \<in> diag (LList A)" |
337 fix M N assume "(M, N) \<in> Id_on (LList A)" |
338 then have "(M, N) \<in> EqLList (diag A)" |
338 then have "(M, N) \<in> EqLList (Id_on A)" |
339 proof coinduct |
339 proof coinduct |
340 case (EqLList M N) |
340 case (EqLList M N) |
341 then obtain L where L: "L \<in> LList A" and MN: "M = L" "N = L" by blast |
341 then obtain L where L: "L \<in> LList A" and MN: "M = L" "N = L" by blast |
342 from L show ?case |
342 from L show ?case |
343 proof cases |
343 proof cases |
344 case NIL with MN have ?EqNIL by simp |
344 case NIL with MN have ?EqNIL by simp |
345 then show ?thesis .. |
345 then show ?thesis .. |
346 next |
346 next |
347 case CONS with MN have ?EqCONS by (simp add: diagI) |
347 case CONS with MN have ?EqCONS by (simp add: Id_onI) |
348 then show ?thesis .. |
348 then show ?thesis .. |
349 qed |
349 qed |
350 qed |
350 qed |
351 } |
351 } |
352 then show "?rhs \<subseteq> ?lhs" by auto |
352 then show "?rhs \<subseteq> ?lhs" by auto |
353 qed |
353 qed |
354 |
354 |
355 lemma EqLList_diag_iff [iff]: "(p \<in> EqLList (diag A)) = (p \<in> diag (LList A))" |
355 lemma EqLList_Id_on_iff [iff]: "(p \<in> EqLList (Id_on A)) = (p \<in> Id_on (LList A))" |
356 by (simp only: EqLList_diag) |
356 by (simp only: EqLList_Id_on) |
357 |
357 |
358 |
358 |
359 text {* |
359 text {* |
360 To show two LLists are equal, exhibit a bisimulation! (Also admits |
360 To show two LLists are equal, exhibit a bisimulation! (Also admits |
361 true equality.) |
361 true equality.) |
365 [consumes 1, case_names EqLList, case_conclusion EqLList EqNIL EqCONS]: |
365 [consumes 1, case_names EqLList, case_conclusion EqLList EqNIL EqCONS]: |
366 assumes r: "(M, N) \<in> r" |
366 assumes r: "(M, N) \<in> r" |
367 and step: "\<And>M N. (M, N) \<in> r \<Longrightarrow> |
367 and step: "\<And>M N. (M, N) \<in> r \<Longrightarrow> |
368 M = NIL \<and> N = NIL \<or> |
368 M = NIL \<and> N = NIL \<or> |
369 (\<exists>a b M' N'. |
369 (\<exists>a b M' N'. |
370 M = CONS a M' \<and> N = CONS b N' \<and> (a, b) \<in> diag A \<and> |
370 M = CONS a M' \<and> N = CONS b N' \<and> (a, b) \<in> Id_on A \<and> |
371 ((M', N') \<in> r \<or> (M', N') \<in> EqLList (diag A)))" |
371 ((M', N') \<in> r \<or> (M', N') \<in> EqLList (Id_on A)))" |
372 shows "M = N" |
372 shows "M = N" |
373 proof - |
373 proof - |
374 from r have "(M, N) \<in> EqLList (diag A)" |
374 from r have "(M, N) \<in> EqLList (Id_on A)" |
375 proof coinduct |
375 proof coinduct |
376 case EqLList |
376 case EqLList |
377 then show ?case by (rule step) |
377 then show ?case by (rule step) |
378 qed |
378 qed |
379 then show ?thesis by auto |
379 then show ?thesis by auto |
385 and fun_NIL: "g NIL \<in> LList A" "f NIL = g NIL" |
385 and fun_NIL: "g NIL \<in> LList A" "f NIL = g NIL" |
386 and fun_CONS: "\<And>x l. x \<in> A \<Longrightarrow> l \<in> LList A \<Longrightarrow> |
386 and fun_CONS: "\<And>x l. x \<in> A \<Longrightarrow> l \<in> LList A \<Longrightarrow> |
387 (f (CONS x l), g (CONS x l)) = (NIL, NIL) \<or> |
387 (f (CONS x l), g (CONS x l)) = (NIL, NIL) \<or> |
388 (\<exists>M N a b. |
388 (\<exists>M N a b. |
389 (f (CONS x l), g (CONS x l)) = (CONS a M, CONS b N) \<and> |
389 (f (CONS x l), g (CONS x l)) = (CONS a M, CONS b N) \<and> |
390 (a, b) \<in> diag A \<and> |
390 (a, b) \<in> Id_on A \<and> |
391 (M, N) \<in> {(f u, g u) | u. u \<in> LList A} \<union> diag (LList A))" |
391 (M, N) \<in> {(f u, g u) | u. u \<in> LList A} \<union> Id_on (LList A))" |
392 (is "\<And>x l. _ \<Longrightarrow> _ \<Longrightarrow> ?fun_CONS x l") |
392 (is "\<And>x l. _ \<Longrightarrow> _ \<Longrightarrow> ?fun_CONS x l") |
393 shows "f M = g M" |
393 shows "f M = g M" |
394 proof - |
394 proof - |
395 let ?bisim = "{(f L, g L) | L. L \<in> LList A}" |
395 let ?bisim = "{(f L, g L) | L. L \<in> LList A}" |
396 have "(f M, g M) \<in> ?bisim" using M by blast |
396 have "(f M, g M) \<in> ?bisim" using M by blast |
399 case (EqLList M N) |
399 case (EqLList M N) |
400 then obtain L where MN: "M = f L" "N = g L" and L: "L \<in> LList A" by blast |
400 then obtain L where MN: "M = f L" "N = g L" and L: "L \<in> LList A" by blast |
401 from L show ?case |
401 from L show ?case |
402 proof (cases L) |
402 proof (cases L) |
403 case NIL |
403 case NIL |
404 with fun_NIL and MN have "(M, N) \<in> diag (LList A)" by auto |
404 with fun_NIL and MN have "(M, N) \<in> Id_on (LList A)" by auto |
405 then have "(M, N) \<in> EqLList (diag A)" .. |
405 then have "(M, N) \<in> EqLList (Id_on A)" .. |
406 then show ?thesis by cases simp_all |
406 then show ?thesis by cases simp_all |
407 next |
407 next |
408 case (CONS a K) |
408 case (CONS a K) |
409 from fun_CONS and `a \<in> A` `K \<in> LList A` |
409 from fun_CONS and `a \<in> A` `K \<in> LList A` |
410 have "?fun_CONS a K" (is "?NIL \<or> ?CONS") . |
410 have "?fun_CONS a K" (is "?NIL \<or> ?CONS") . |
411 then show ?thesis |
411 then show ?thesis |
412 proof |
412 proof |
413 assume ?NIL |
413 assume ?NIL |
414 with MN CONS have "(M, N) \<in> diag (LList A)" by auto |
414 with MN CONS have "(M, N) \<in> Id_on (LList A)" by auto |
415 then have "(M, N) \<in> EqLList (diag A)" .. |
415 then have "(M, N) \<in> EqLList (Id_on A)" .. |
416 then show ?thesis by cases simp_all |
416 then show ?thesis by cases simp_all |
417 next |
417 next |
418 assume ?CONS |
418 assume ?CONS |
419 with CONS obtain a b M' N' where |
419 with CONS obtain a b M' N' where |
420 fg: "(f L, g L) = (CONS a M', CONS b N')" |
420 fg: "(f L, g L) = (CONS a M', CONS b N')" |
421 and ab: "(a, b) \<in> diag A" |
421 and ab: "(a, b) \<in> Id_on A" |
422 and M'N': "(M', N') \<in> ?bisim \<union> diag (LList A)" |
422 and M'N': "(M', N') \<in> ?bisim \<union> Id_on (LList A)" |
423 by blast |
423 by blast |
424 from M'N' show ?thesis |
424 from M'N' show ?thesis |
425 proof |
425 proof |
426 assume "(M', N') \<in> ?bisim" |
426 assume "(M', N') \<in> ?bisim" |
427 with MN fg ab show ?thesis by simp |
427 with MN fg ab show ?thesis by simp |
428 next |
428 next |
429 assume "(M', N') \<in> diag (LList A)" |
429 assume "(M', N') \<in> Id_on (LList A)" |
430 then have "(M', N') \<in> EqLList (diag A)" .. |
430 then have "(M', N') \<in> EqLList (Id_on A)" .. |
431 with MN fg ab show ?thesis by simp |
431 with MN fg ab show ?thesis by simp |
432 qed |
432 qed |
433 qed |
433 qed |
434 qed |
434 qed |
435 qed |
435 qed |