558 | bs3: "ASEQ bs1 (AONE bs2) r \<leadsto> fuse (bs1@bs2) r" |
558 | bs3: "ASEQ bs1 (AONE bs2) r \<leadsto> fuse (bs1@bs2) r" |
559 | bs4: "r1 \<leadsto> r2 \<Longrightarrow> ASEQ bs r1 r3 \<leadsto> ASEQ bs r2 r3" |
559 | bs4: "r1 \<leadsto> r2 \<Longrightarrow> ASEQ bs r1 r3 \<leadsto> ASEQ bs r2 r3" |
560 | bs5: "r3 \<leadsto> r4 \<Longrightarrow> ASEQ bs r1 r3 \<leadsto> ASEQ bs r1 r4" |
560 | bs5: "r3 \<leadsto> r4 \<Longrightarrow> ASEQ bs r1 r3 \<leadsto> ASEQ bs r1 r4" |
561 | bs6: "AALTs bs [] \<leadsto> AZERO" |
561 | bs6: "AALTs bs [] \<leadsto> AZERO" |
562 | bs7: "AALTs bs [r] \<leadsto> fuse bs r" |
562 | bs7: "AALTs bs [r] \<leadsto> fuse bs r" |
563 | bs10: "rs1 s\<leadsto> rs2 \<Longrightarrow> AALTs bs rs1 \<leadsto> AALTs bs rs2" |
563 | bs8: "rs1 s\<leadsto> rs2 \<Longrightarrow> AALTs bs rs1 \<leadsto> AALTs bs rs2" |
564 | ss1: "[] s\<leadsto> []" |
564 | ss1: "[] s\<leadsto> []" |
565 | ss2: "rs1 s\<leadsto> rs2 \<Longrightarrow> (r # rs1) s\<leadsto> (r # rs2)" |
565 | ss2: "rs1 s\<leadsto> rs2 \<Longrightarrow> (r # rs1) s\<leadsto> (r # rs2)" |
566 | ss3: "r1 \<leadsto> r2 \<Longrightarrow> (r1 # rs) s\<leadsto> (r2 # rs)" |
566 | ss3: "r1 \<leadsto> r2 \<Longrightarrow> (r1 # rs) s\<leadsto> (r2 # rs)" |
567 | ss4: "(AZERO # rs) s\<leadsto> rs" |
567 | ss4: "(AZERO # rs) s\<leadsto> rs" |
568 | ss5: "(AALTs bs1 rs1 # rsb) s\<leadsto> ((map (fuse bs1) rs1) @ rsb)" |
568 | ss5: "(AALTs bs1 rs1 # rsb) s\<leadsto> ((map (fuse bs1) rs1) @ rsb)" |
584 |
584 |
585 lemma r_in_rstar: |
585 lemma r_in_rstar: |
586 shows "r1 \<leadsto> r2 \<Longrightarrow> r1 \<leadsto>* r2" |
586 shows "r1 \<leadsto> r2 \<Longrightarrow> r1 \<leadsto>* r2" |
587 using rrewrites.intros(1) rrewrites.intros(2) by blast |
587 using rrewrites.intros(1) rrewrites.intros(2) by blast |
588 |
588 |
589 lemma srewrites_single : |
|
590 shows "rs1 s\<leadsto> rs2 \<Longrightarrow> rs1 s\<leadsto>* rs2" |
|
591 using rrewrites.intros(1) rrewrites.intros(2) by blast |
|
592 |
|
593 |
|
594 lemma rrewrites_trans[trans]: |
589 lemma rrewrites_trans[trans]: |
595 assumes a1: "r1 \<leadsto>* r2" and a2: "r2 \<leadsto>* r3" |
590 assumes a1: "r1 \<leadsto>* r2" and a2: "r2 \<leadsto>* r3" |
596 shows "r1 \<leadsto>* r3" |
591 shows "r1 \<leadsto>* r3" |
597 using a2 a1 |
592 using a2 a1 |
598 apply(induct r2 r3 arbitrary: r1 rule: rrewrites.induct) |
593 apply(induct r2 r3 arbitrary: r1 rule: rrewrites.induct) |
611 |
606 |
612 lemma contextrewrites0: |
607 lemma contextrewrites0: |
613 "rs1 s\<leadsto>* rs2 \<Longrightarrow> AALTs bs rs1 \<leadsto>* AALTs bs rs2" |
608 "rs1 s\<leadsto>* rs2 \<Longrightarrow> AALTs bs rs1 \<leadsto>* AALTs bs rs2" |
614 apply(induct rs1 rs2 rule: srewrites.inducts) |
609 apply(induct rs1 rs2 rule: srewrites.inducts) |
615 apply simp |
610 apply simp |
616 using bs10 r_in_rstar rrewrites_trans by blast |
611 using bs8 r_in_rstar rrewrites_trans by blast |
617 |
612 |
618 lemma contextrewrites1: |
613 lemma contextrewrites1: |
619 "r \<leadsto>* r' \<Longrightarrow> AALTs bs (r # rs) \<leadsto>* AALTs bs (r' # rs)" |
614 "r \<leadsto>* r' \<Longrightarrow> AALTs bs (r # rs) \<leadsto>* AALTs bs (r' # rs)" |
620 apply(induct r r' rule: rrewrites.induct) |
615 apply(induct r r' rule: rrewrites.induct) |
621 apply simp |
616 apply simp |
622 using bs10 ss3 by blast |
617 using bs8 ss3 by blast |
623 |
618 |
624 lemma srewrite1: |
619 lemma srewrite1: |
625 shows "rs1 s\<leadsto> rs2 \<Longrightarrow> (rs @ rs1) s\<leadsto> (rs @ rs2)" |
620 shows "rs1 s\<leadsto> rs2 \<Longrightarrow> (rs @ rs1) s\<leadsto> (rs @ rs2)" |
626 apply(induct rs) |
621 apply(induct rs) |
627 apply(auto) |
622 apply(auto) |
635 |
630 |
636 lemma srewrite2: |
631 lemma srewrite2: |
637 shows "r1 \<leadsto> r2 \<Longrightarrow> True" |
632 shows "r1 \<leadsto> r2 \<Longrightarrow> True" |
638 and "rs1 s\<leadsto> rs2 \<Longrightarrow> (rs1 @ rs) s\<leadsto>* (rs2 @ rs)" |
633 and "rs1 s\<leadsto> rs2 \<Longrightarrow> (rs1 @ rs) s\<leadsto>* (rs2 @ rs)" |
639 apply(induct rule: rrewrite_srewrite.inducts) |
634 apply(induct rule: rrewrite_srewrite.inducts) |
640 apply(auto) |
635 apply(auto) |
641 apply (metis append_Cons append_Nil srewrites1) |
636 apply (metis append_Cons append_Nil srewrites1) |
642 apply(meson srewrites.simps ss3) |
637 apply(meson srewrites.simps ss3) |
643 apply (meson srewrites.simps ss4) |
638 apply (meson srewrites.simps ss4) |
644 apply (meson srewrites.simps ss5) |
639 apply (meson srewrites.simps ss5) |
645 by (metis append_Cons append_Nil srewrites.simps ss6) |
640 by (metis append_Cons append_Nil srewrites.simps ss6) |
646 |
641 |
647 |
642 |
664 lemma srewrites6: |
659 lemma srewrites6: |
665 assumes "r1 \<leadsto>* r2" |
660 assumes "r1 \<leadsto>* r2" |
666 shows "[r1] s\<leadsto>* [r2]" |
661 shows "[r1] s\<leadsto>* [r2]" |
667 using assms |
662 using assms |
668 apply(induct r1 r2 rule: rrewrites.induct) |
663 apply(induct r1 r2 rule: rrewrites.induct) |
669 apply(auto) |
664 apply(auto) |
670 by (meson srewrites.simps srewrites_trans ss3) |
665 by (meson srewrites.simps srewrites_trans ss3) |
671 |
666 |
672 lemma srewrites7: |
667 lemma srewrites7: |
673 assumes "rs3 s\<leadsto>* rs4" "r1 \<leadsto>* r2" |
668 assumes "rs3 s\<leadsto>* rs4" "r1 \<leadsto>* r2" |
674 shows "(r1 # rs3) s\<leadsto>* (r2 # rs4)" |
669 shows "(r1 # rs3) s\<leadsto>* (r2 # rs4)" |
675 using assms |
670 using assms |
676 by (smt (verit, best) append_Cons append_Nil srewrites1 srewrites3 srewrites6 srewrites_trans) |
671 by (smt (verit, del_insts) append.simps srewrites1 srewrites3 srewrites6 srewrites_trans) |
677 |
672 |
678 lemma ss6_stronger_aux: |
673 lemma ss6_stronger_aux: |
679 shows "(rs1 @ rs2) s\<leadsto>* (rs1 @ distinctBy rs2 erase (set (map erase rs1)))" |
674 shows "(rs1 @ rs2) s\<leadsto>* (rs1 @ distinctBy rs2 erase (set (map erase rs1)))" |
680 apply(induct rs2 arbitrary: rs1) |
675 apply(induct rs2 arbitrary: rs1) |
681 apply(auto) |
676 apply(auto) |
682 apply (smt (verit, best) append.assoc append.right_neutral append_Cons append_Nil split_list srewrite2(2) srewrites_trans ss6) |
677 apply (smt (verit, best) append.assoc append.right_neutral append_Cons append_Nil split_list srewrite2(2) srewrites_trans ss6) |
686 |
681 |
687 lemma ss6_stronger: |
682 lemma ss6_stronger: |
688 shows "rs1 s\<leadsto>* distinctBy rs1 erase {}" |
683 shows "rs1 s\<leadsto>* distinctBy rs1 erase {}" |
689 using ss6_stronger_aux[of "[]" _] by auto |
684 using ss6_stronger_aux[of "[]" _] by auto |
690 |
685 |
691 |
|
692 lemma rewrite_preserves_fuse: |
686 lemma rewrite_preserves_fuse: |
693 shows "r2 \<leadsto> r3 \<Longrightarrow> fuse bs r2 \<leadsto> fuse bs r3" |
687 shows "r2 \<leadsto> r3 \<Longrightarrow> fuse bs r2 \<leadsto> fuse bs r3" |
694 and "rs2 s\<leadsto> rs3 \<Longrightarrow> map (fuse bs) rs2 s\<leadsto>* map (fuse bs) rs3" |
688 and "rs2 s\<leadsto> rs3 \<Longrightarrow> map (fuse bs) rs2 s\<leadsto> map (fuse bs) rs3" |
695 proof(induct rule: rrewrite_srewrite.inducts) |
689 proof(induct rule: rrewrite_srewrite.inducts) |
696 case (bs3 bs1 bs2 r) |
690 case (bs3 bs1 bs2 r) |
697 then show ?case |
691 then show "fuse bs (ASEQ bs1 (AONE bs2) r) \<leadsto> fuse bs (fuse (bs1 @ bs2) r)" |
698 by (metis fuse.simps(5) fuse_append rrewrite_srewrite.bs3) |
692 by (metis fuse.simps(5) fuse_append rrewrite_srewrite.bs3) |
699 next |
693 next |
700 case (bs7 bs r) |
694 case (bs7 bs1 r) |
701 then show ?case |
695 then show "fuse bs (AALTs bs1 [r]) \<leadsto> fuse bs (fuse bs1 r)" |
702 by (metis fuse.simps(4) fuse_append rrewrite_srewrite.bs7) |
696 by (metis fuse.simps(4) fuse_append rrewrite_srewrite.bs7) |
703 next |
697 next |
704 case (ss2 rs1 rs2 r) |
698 case (ss2 rs1 rs2 r) |
705 then show ?case |
699 then show "map (fuse bs) (r # rs1) s\<leadsto> map (fuse bs) (r # rs2)" |
706 using srewrites7 by force |
700 by (simp add: rrewrite_srewrite.ss2) |
707 next |
701 next |
708 case (ss3 r1 r2 rs) |
702 case (ss3 r1 r2 rs) |
709 then show ?case by (simp add: r_in_rstar srewrites7) |
703 then show "map (fuse bs) (r1 # rs) s\<leadsto> map (fuse bs) (r2 # rs)" |
|
704 by (simp add: rrewrite_srewrite.ss3) |
710 next |
705 next |
711 case (ss5 bs1 rs1 rsb) |
706 case (ss5 bs1 rs1 rsb) |
712 then show ?case |
707 have "map (fuse bs) (AALTs bs1 rs1 # rsb) = AALTs (bs @ bs1) rs1 # (map (fuse bs) rsb)" by simp |
|
708 also have "... s\<leadsto> ((map (fuse (bs @ bs1)) rs1) @ (map (fuse bs) rsb))" |
|
709 by (simp add: rrewrite_srewrite.ss5) |
|
710 finally show "map (fuse bs) (AALTs bs1 rs1 # rsb) s\<leadsto> map (fuse bs) (map (fuse bs1) rs1 @ rsb)" |
|
711 by (simp add: comp_def fuse_append) |
|
712 next |
|
713 case (ss6 a1 a2 rsa rsb rsc) |
|
714 then show "map (fuse bs) (rsa @ [a1] @ rsb @ [a2] @ rsc) s\<leadsto> map (fuse bs) (rsa @ [a1] @ rsb @ rsc)" |
713 apply(simp) |
715 apply(simp) |
714 by (metis (mono_tags, lifting) comp_def fuse_append map_eq_conv rrewrite_srewrite.ss5 srewrites.simps) |
|
715 next |
|
716 case (ss6 a1 a2 rsa rsb rsc) |
|
717 then show ?case |
|
718 apply(simp) |
|
719 apply(rule srewrites_single) |
|
720 apply(rule rrewrite_srewrite.ss6[simplified]) |
716 apply(rule rrewrite_srewrite.ss6[simplified]) |
721 apply(simp add: erase_fuse) |
717 apply(simp add: erase_fuse) |
722 done |
718 done |
723 qed (auto intro: rrewrite_srewrite.intros) |
719 qed (auto intro: rrewrite_srewrite.intros) |
724 |
|
725 |
720 |
726 lemma rewrites_fuse: |
721 lemma rewrites_fuse: |
727 assumes "r1 \<leadsto>* r2" |
722 assumes "r1 \<leadsto>* r2" |
728 shows "fuse bs r1 \<leadsto>* fuse bs r2" |
723 shows "fuse bs r1 \<leadsto>* fuse bs r2" |
729 using assms |
724 using assms |
730 apply(induction r1 r2 arbitrary: bs rule: rrewrites.induct) |
725 apply(induction r1 r2 arbitrary: bs rule: rrewrites.induct) |
731 apply(auto intro: rewrite_preserves_fuse rrewrites_trans) |
726 apply(auto intro: rewrite_preserves_fuse) |
732 done |
727 done |
733 |
728 |
734 |
729 |
735 lemma star_seq: |
730 lemma star_seq: |
736 assumes "r1 \<leadsto>* r2" |
731 assumes "r1 \<leadsto>* r2" |
769 lemma bsimp_AALTs_rewrites: |
764 lemma bsimp_AALTs_rewrites: |
770 shows "AALTs bs1 rs \<leadsto>* bsimp_AALTs bs1 rs" |
765 shows "AALTs bs1 rs \<leadsto>* bsimp_AALTs bs1 rs" |
771 by (smt (verit) bs6 bs7 bsimp_AALTs.elims rrewrites.simps) |
766 by (smt (verit) bs6 bs7 bsimp_AALTs.elims rrewrites.simps) |
772 |
767 |
773 lemma trivialbsimp_srewrites: |
768 lemma trivialbsimp_srewrites: |
774 "\<lbrakk>\<And>x. x \<in> set rs \<Longrightarrow> x \<leadsto>* f x \<rbrakk> \<Longrightarrow> rs s\<leadsto>* (map f rs)" |
769 assumes "\<And>x. x \<in> set rs \<Longrightarrow> x \<leadsto>* f x" |
|
770 shows "rs s\<leadsto>* (map f rs)" |
|
771 using assms |
775 apply(induction rs) |
772 apply(induction rs) |
776 apply simp |
773 apply(simp_all add: srewrites7) |
777 apply(simp) |
774 done |
778 using srewrites7 by auto |
|
779 |
|
780 |
|
781 |
775 |
782 lemma fltsfrewrites: "rs s\<leadsto>* flts rs" |
776 lemma fltsfrewrites: "rs s\<leadsto>* flts rs" |
783 apply(induction rs rule: flts.induct) |
777 apply(induction rs rule: flts.induct) |
784 apply(auto intro: rrewrite_srewrite.intros) |
778 apply(auto intro: rrewrite_srewrite.intros) |
785 apply (meson srewrites.simps srewrites1 ss5) |
779 apply (meson srewrites.simps srewrites1 ss5) |
902 qed (simp_all) |
896 qed (simp_all) |
903 |
897 |
904 |
898 |
905 lemma to_zero_in_alt: |
899 lemma to_zero_in_alt: |
906 shows "AALT bs (ASEQ [] AZERO r) r2 \<leadsto> AALT bs AZERO r2" |
900 shows "AALT bs (ASEQ [] AZERO r) r2 \<leadsto> AALT bs AZERO r2" |
907 by (simp add: bs1 bs10 ss3) |
901 by (simp add: bs1 bs8 ss3) |
908 |
902 |
909 |
903 |
910 |
904 |
911 lemma bder_fuse_list: |
905 lemma bder_fuse_list: |
912 shows "map (bder c \<circ> fuse bs1) rs1 = map (fuse bs1 \<circ> bder c) rs1" |
906 shows "map (bder c \<circ> fuse bs1) rs1 = map (fuse bs1 \<circ> bder c) rs1" |
913 apply(induction rs1) |
907 apply(induction rs1) |
914 apply(simp_all add: bder_fuse) |
908 apply(simp_all add: bder_fuse) |
915 done |
909 done |
916 |
|
917 |
910 |
918 lemma rewrite_preserves_bder: |
911 lemma rewrite_preserves_bder: |
919 shows "r1 \<leadsto> r2 \<Longrightarrow> bder c r1 \<leadsto>* bder c r2" |
912 shows "r1 \<leadsto> r2 \<Longrightarrow> bder c r1 \<leadsto>* bder c r2" |
920 and "rs1 s\<leadsto> rs2 \<Longrightarrow> map (bder c) rs1 s\<leadsto>* map (bder c) rs2" |
913 and "rs1 s\<leadsto> rs2 \<Longrightarrow> map (bder c) rs1 s\<leadsto>* map (bder c) rs2" |
921 proof(induction rule: rrewrite_srewrite.inducts) |
914 proof(induction rule: rrewrite_srewrite.inducts) |
930 by (simp add: r_in_rstar rrewrite_srewrite.bs2) |
923 by (simp add: r_in_rstar rrewrite_srewrite.bs2) |
931 next |
924 next |
932 case (bs3 bs1 bs2 r) |
925 case (bs3 bs1 bs2 r) |
933 show "bder c (ASEQ bs1 (AONE bs2) r) \<leadsto>* bder c (fuse (bs1 @ bs2) r)" |
926 show "bder c (ASEQ bs1 (AONE bs2) r) \<leadsto>* bder c (fuse (bs1 @ bs2) r)" |
934 apply(simp) |
927 apply(simp) |
935 by (metis (no_types, lifting) bder_fuse bs10 bs7 fuse_append rrewrites.simps ss4 to_zero_in_alt) |
928 by (metis (no_types, lifting) bder_fuse bs8 bs7 fuse_append rrewrites.simps ss4 to_zero_in_alt) |
936 next |
929 next |
937 case (bs4 r1 r2 bs r3) |
930 case (bs4 r1 r2 bs r3) |
938 have as: "r1 \<leadsto> r2" by fact |
931 have as: "r1 \<leadsto> r2" by fact |
939 have IH: "bder c r1 \<leadsto>* bder c r2" by fact |
932 have IH: "bder c r1 \<leadsto>* bder c r2" by fact |
940 from as IH show "bder c (ASEQ bs r1 r3) \<leadsto>* bder c (ASEQ bs r2 r3)" |
933 from as IH show "bder c (ASEQ bs r1 r3) \<leadsto>* bder c (ASEQ bs r2 r3)" |
955 next |
948 next |
956 case (bs7 bs r) |
949 case (bs7 bs r) |
957 show "bder c (AALTs bs [r]) \<leadsto>* bder c (fuse bs r)" |
950 show "bder c (AALTs bs [r]) \<leadsto>* bder c (fuse bs r)" |
958 by (simp add: bder_fuse r_in_rstar rrewrite_srewrite.bs7) |
951 by (simp add: bder_fuse r_in_rstar rrewrite_srewrite.bs7) |
959 next |
952 next |
960 case (bs10 rs1 rs2 bs) |
953 case (bs8 rs1 rs2 bs) |
961 have IH1: "map (bder c) rs1 s\<leadsto>* map (bder c) rs2" by fact |
954 have IH1: "map (bder c) rs1 s\<leadsto>* map (bder c) rs2" by fact |
962 then show "bder c (AALTs bs rs1) \<leadsto>* bder c (AALTs bs rs2)" |
955 then show "bder c (AALTs bs rs1) \<leadsto>* bder c (AALTs bs rs2)" |
963 using contextrewrites0 by force |
956 using contextrewrites0 by force |
964 next |
957 next |
965 case ss1 |
958 case ss1 |
1026 show "bmkeps (bders r s) = bmkeps (bders_simp r s)" using assms |
1019 show "bmkeps (bders r s) = bmkeps (bders_simp r s)" using assms |
1027 by (rule rewrites_bmkeps) |
1020 by (rule rewrites_bmkeps) |
1028 qed |
1021 qed |
1029 |
1022 |
1030 |
1023 |
1031 |
|
1032 |
|
1033 theorem main_blexer_simp: |
1024 theorem main_blexer_simp: |
1034 shows "blexer r s = blexer_simp r s" |
1025 shows "blexer r s = blexer_simp r s" |
1035 unfolding blexer_def blexer_simp_def |
1026 unfolding blexer_def blexer_simp_def |
1036 by (metis central main_aux rewrites_bnullable_eq) |
1027 by (metis central main_aux rewrites_bnullable_eq) |
1037 |
1028 |