867 |
888 |
868 end |
889 end |
869 |
890 |
870 section {* Waiting queues and threads *} |
891 section {* Waiting queues and threads *} |
871 |
892 |
872 context valid_trace_e |
893 text {* |
873 begin |
894 This section shows that all threads withing waiting queues are |
874 |
895 in the @{term threads}-set. In other words, @{term threads} covers |
875 lemma wq_out_inv: |
896 all the threads in waiting queue. |
876 assumes s_in: "thread \<in> set (wq s cs)" |
897 |
877 and s_hd: "thread = hd (wq s cs)" |
898 The proof follows the same pattern as @{thm valid_trace.wq_distinct}. |
878 and s_i: "thread \<noteq> hd (wq (e#s) cs)" |
899 The desired property is shown to be kept by all operations (or events) |
879 shows "e = V thread cs" |
900 in their respective locales, and finally the main lemmas is |
880 proof(cases e) |
901 derived by assembling the invariant keeping results of the locales. |
881 -- {* There are only two non-trivial cases: *} |
902 *} |
882 case (V th cs1) |
903 |
883 show ?thesis |
904 context valid_trace_create |
884 proof(cases "cs1 = cs") |
905 begin |
885 case True |
906 |
886 have "PIP s (V th cs)" using pip_e[unfolded V[unfolded True]] . |
907 lemma |
887 thus ?thesis |
|
888 proof(cases) |
|
889 case (thread_V) |
|
890 moreover have "th = thread" using thread_V(2) s_hd |
|
891 by (unfold s_holding_def wq_def, simp) |
|
892 ultimately show ?thesis using V True by simp |
|
893 qed |
|
894 qed (insert assms V, auto simp:wq_def Let_def split:if_splits) |
|
895 next |
|
896 case (P th cs1) |
|
897 show ?thesis |
|
898 proof(cases "cs1 = cs") |
|
899 case True |
|
900 with P have "wq (e#s) cs = wq_fun (schs s) cs @ [th]" |
|
901 by (auto simp:wq_def Let_def split:if_splits) |
|
902 with s_i s_hd s_in have False |
|
903 by (metis empty_iff hd_append2 list.set(1) wq_def) |
|
904 thus ?thesis by simp |
|
905 qed (insert assms P, auto simp:wq_def Let_def split:if_splits) |
|
906 qed (insert assms, auto simp:wq_def Let_def split:if_splits) |
|
907 |
|
908 lemma wq_in_inv: |
|
909 assumes s_ni: "thread \<notin> set (wq s cs)" |
|
910 and s_i: "thread \<in> set (wq (e#s) cs)" |
|
911 shows "e = P thread cs" |
|
912 proof(cases e) |
|
913 -- {* This is the only non-trivial case: *} |
|
914 case (V th cs1) |
|
915 have False |
|
916 proof(cases "cs1 = cs") |
|
917 case True |
|
918 show ?thesis |
|
919 proof(cases "(wq s cs1)") |
|
920 case (Cons w_hd w_tl) |
|
921 have "set (wq (e#s) cs) \<subseteq> set (wq s cs)" |
|
922 proof - |
|
923 have "(wq (e#s) cs) = (SOME q. distinct q \<and> set q = set w_tl)" |
|
924 using Cons V by (auto simp:wq_def Let_def True split:if_splits) |
|
925 moreover have "set ... \<subseteq> set (wq s cs)" |
|
926 proof(rule someI2) |
|
927 show "distinct w_tl \<and> set w_tl = set w_tl" |
|
928 by (metis distinct.simps(2) local.Cons wq_distinct) |
|
929 qed (insert Cons True, auto) |
|
930 ultimately show ?thesis by simp |
|
931 qed |
|
932 with assms show ?thesis by auto |
|
933 qed (insert assms V True, auto simp:wq_def Let_def split:if_splits) |
|
934 qed (insert assms V, auto simp:wq_def Let_def split:if_splits) |
|
935 thus ?thesis by auto |
|
936 qed (insert assms, auto simp:wq_def Let_def split:if_splits) |
|
937 |
|
938 end |
|
939 |
|
940 lemma (in valid_trace_create) |
|
941 th_not_in_threads: "th \<notin> threads s" |
908 th_not_in_threads: "th \<notin> threads s" |
942 proof - |
909 proof - |
943 from pip_e[unfolded is_create] |
910 from pip_e[unfolded is_create] |
944 show ?thesis by (cases, simp) |
911 show ?thesis by (cases, simp) |
945 qed |
912 qed |
946 |
913 |
947 lemma (in valid_trace_create) |
914 lemma |
948 threads_es [simp]: "threads (e#s) = threads s \<union> {th}" |
915 threads_es [simp]: "threads (e#s) = threads s \<union> {th}" |
949 by (unfold is_create, simp) |
916 by (unfold is_create, simp) |
950 |
917 |
951 lemma (in valid_trace_exit) |
918 lemma wq_threads_kept: |
952 threads_es [simp]: "threads (e#s) = threads s - {th}" |
919 assumes "\<And> th' cs'. th' \<in> set (wq s cs') \<Longrightarrow> th' \<in> threads s" |
|
920 and "th' \<in> set (wq (e#s) cs')" |
|
921 shows "th' \<in> threads (e#s)" |
|
922 proof - |
|
923 have "th' \<in> threads s" |
|
924 proof - |
|
925 from assms(2)[unfolded wq_kept] |
|
926 have "th' \<in> set (wq s cs')" . |
|
927 from assms(1)[OF this] show ?thesis . |
|
928 qed |
|
929 with threads_es show ?thesis by simp |
|
930 qed |
|
931 |
|
932 end |
|
933 |
|
934 context valid_trace_exit |
|
935 begin |
|
936 |
|
937 lemma threads_es [simp]: "threads (e#s) = threads s - {th}" |
953 by (unfold is_exit, simp) |
938 by (unfold is_exit, simp) |
954 |
939 |
955 lemma (in valid_trace_p) |
940 lemma |
956 threads_es [simp]: "threads (e#s) = threads s" |
941 th_not_in_wq: "th \<notin> set (wq s cs)" |
957 by (unfold is_p, simp) |
942 proof - |
958 |
943 from pip_e[unfolded is_exit] |
959 lemma (in valid_trace_v) |
944 show ?thesis |
|
945 by (cases, unfold holdents_def s_holding_def, fold wq_def, |
|
946 auto elim!:runing_wqE) |
|
947 qed |
|
948 |
|
949 lemma wq_threads_kept: |
|
950 assumes "\<And> th' cs'. th' \<in> set (wq s cs') \<Longrightarrow> th' \<in> threads s" |
|
951 and "th' \<in> set (wq (e#s) cs')" |
|
952 shows "th' \<in> threads (e#s)" |
|
953 proof - |
|
954 have "th' \<in> threads s" |
|
955 proof - |
|
956 from assms(2)[unfolded wq_kept] |
|
957 have "th' \<in> set (wq s cs')" . |
|
958 from assms(1)[OF this] show ?thesis . |
|
959 qed |
|
960 moreover have "th' \<noteq> th" |
|
961 proof |
|
962 assume otherwise: "th' = th" |
|
963 from assms(2)[unfolded wq_kept] |
|
964 have "th' \<in> set (wq s cs')" . |
|
965 with th_not_in_wq[folded otherwise] |
|
966 show False by simp |
|
967 qed |
|
968 ultimately show ?thesis |
|
969 by (unfold threads_es, simp) |
|
970 qed |
|
971 |
|
972 end |
|
973 |
|
974 context valid_trace_v |
|
975 begin |
|
976 |
|
977 lemma |
960 threads_es [simp]: "threads (e#s) = threads s" |
978 threads_es [simp]: "threads (e#s) = threads s" |
961 by (unfold is_v, simp) |
979 by (unfold is_v, simp) |
962 |
980 |
963 lemma (in valid_trace_v) |
981 lemma |
964 th_not_in_rest[simp]: "th \<notin> set rest" |
982 th_not_in_rest: "th \<notin> set rest" |
965 proof |
983 proof |
966 assume otherwise: "th \<in> set rest" |
984 assume otherwise: "th \<in> set rest" |
967 have "distinct (wq s cs)" by (simp add: wq_distinct) |
985 have "distinct (wq s cs)" by (simp add: wq_distinct) |
968 from this[unfolded wq_s_cs] and otherwise |
986 from this[unfolded wq_s_cs] and otherwise |
969 show False by auto |
987 show False by auto |
970 qed |
988 qed |
971 |
989 |
972 lemma (in valid_trace_v) distinct_rest: "distinct rest" |
990 lemma distinct_rest: "distinct rest" |
973 by (simp add: distinct_tl rest_def wq_distinct) |
991 by (simp add: distinct_tl rest_def wq_distinct) |
974 |
992 |
975 lemma (in valid_trace_v) |
993 lemma |
976 set_wq_es_cs [simp]: "set (wq (e#s) cs) = set (wq s cs) - {th}" |
994 set_wq_es_cs [simp]: "set (wq (e#s) cs) = set (wq s cs) - {th}" |
977 proof(unfold wq_es_cs wq'_def, rule someI2) |
995 proof(unfold wq_es_cs wq'_def, rule someI2) |
978 show "distinct rest \<and> set rest = set rest" |
996 show "distinct rest \<and> set rest = set rest" |
979 by (simp add: distinct_rest) |
997 by (simp add: distinct_rest) |
980 next |
998 next |
981 fix x |
999 fix x |
982 assume "distinct x \<and> set x = set rest" |
1000 assume "distinct x \<and> set x = set rest" |
983 thus "set x = set (wq s cs) - {th}" |
1001 thus "set x = set (wq s cs) - {th}" |
984 by (unfold wq_s_cs, simp) |
1002 by (unfold wq_s_cs, simp add:th_not_in_rest) |
985 qed |
1003 qed |
986 |
1004 |
987 lemma (in valid_trace_exit) |
1005 lemma wq_threads_kept: |
988 th_not_in_wq: "th \<notin> set (wq s cs)" |
1006 assumes "\<And> th' cs'. th' \<in> set (wq s cs') \<Longrightarrow> th' \<in> threads s" |
989 proof - |
1007 and "th' \<in> set (wq (e#s) cs')" |
990 from pip_e[unfolded is_exit] |
1008 shows "th' \<in> threads (e#s)" |
991 show ?thesis |
1009 proof(cases "cs' = cs") |
992 by (cases, unfold holdents_def s_holding_def, fold wq_def, |
1010 case True |
993 auto elim!:runing_wqE) |
1011 have " th' \<in> threads s" |
994 qed |
1012 proof - |
995 |
1013 from assms(2)[unfolded True set_wq_es_cs] |
|
1014 have "th' \<in> set (wq s cs) - {th}" . |
|
1015 hence "th' \<in> set (wq s cs)" by simp |
|
1016 from assms(1)[OF this] |
|
1017 show ?thesis . |
|
1018 qed |
|
1019 with threads_es show ?thesis by simp |
|
1020 next |
|
1021 case False |
|
1022 have "th' \<in> threads s" |
|
1023 proof - |
|
1024 from wq_neq_simp[OF False] |
|
1025 have "wq (e # s) cs' = wq s cs'" . |
|
1026 from assms(2)[unfolded this] |
|
1027 have "th' \<in> set (wq s cs')" . |
|
1028 from assms(1)[OF this] |
|
1029 show ?thesis . |
|
1030 qed |
|
1031 with threads_es show ?thesis by simp |
|
1032 qed |
|
1033 end |
|
1034 |
|
1035 context valid_trace_p |
|
1036 begin |
|
1037 |
|
1038 lemma threads_es [simp]: "threads (e#s) = threads s" |
|
1039 by (unfold is_p, simp) |
|
1040 |
|
1041 lemma ready_th_s: "th \<in> readys s" |
|
1042 using runing_th_s |
|
1043 by (unfold runing_def, auto) |
|
1044 |
|
1045 lemma live_th_s: "th \<in> threads s" |
|
1046 using readys_threads ready_th_s by auto |
|
1047 |
|
1048 lemma wq_threads_kept: |
|
1049 assumes "\<And> th' cs'. th' \<in> set (wq s cs') \<Longrightarrow> th' \<in> threads s" |
|
1050 and "th' \<in> set (wq (e#s) cs')" |
|
1051 shows "th' \<in> threads (e#s)" |
|
1052 proof(cases "cs' = cs") |
|
1053 case True |
|
1054 from assms(2)[unfolded True wq_es_cs] |
|
1055 have "th' \<in> set (wq s cs) \<or> th' = th" by auto |
|
1056 thus ?thesis |
|
1057 proof |
|
1058 assume "th' \<in> set (wq s cs)" |
|
1059 from assms(1)[OF this] have "th' \<in> threads s" . |
|
1060 with threads_es |
|
1061 show ?thesis by simp |
|
1062 next |
|
1063 assume "th' = th" |
|
1064 with live_th_s have "th' \<in> threads s" by simp |
|
1065 with threads_es show ?thesis by simp |
|
1066 qed |
|
1067 next |
|
1068 case False |
|
1069 have "th' \<in> threads s" |
|
1070 proof - |
|
1071 from wq_neq_simp[OF False] |
|
1072 have "wq (e # s) cs' = wq s cs'" . |
|
1073 from assms(2)[unfolded this] |
|
1074 have "th' \<in> set (wq s cs')" . |
|
1075 from assms(1)[OF this] |
|
1076 show ?thesis . |
|
1077 qed |
|
1078 with threads_es show ?thesis by simp |
|
1079 qed |
|
1080 |
|
1081 end |
|
1082 |
|
1083 context valid_trace_set |
|
1084 begin |
|
1085 |
|
1086 lemma threads_kept[simp]: |
|
1087 "threads (e#s) = threads s" |
|
1088 by (unfold is_set, simp) |
|
1089 |
|
1090 lemma wq_threads_kept: |
|
1091 assumes "\<And> th' cs'. th' \<in> set (wq s cs') \<Longrightarrow> th' \<in> threads s" |
|
1092 and "th' \<in> set (wq (e#s) cs')" |
|
1093 shows "th' \<in> threads (e#s)" |
|
1094 proof - |
|
1095 have "th' \<in> threads s" |
|
1096 using assms(1)[OF assms(2)[unfolded wq_kept]] . |
|
1097 with threads_kept show ?thesis by simp |
|
1098 qed |
|
1099 |
|
1100 end |
|
1101 |
|
1102 text {* |
|
1103 The is the main lemma of this section, which is derived |
|
1104 by induction, case analysis on event @{text e} and |
|
1105 assembling the @{text "wq_threads_kept"}-results of |
|
1106 all possible cases of @{text "e"}. |
|
1107 *} |
996 lemma (in valid_trace) wq_threads: |
1108 lemma (in valid_trace) wq_threads: |
997 assumes "th \<in> set (wq s cs)" |
1109 assumes "th \<in> set (wq s cs)" |
998 shows "th \<in> threads s" |
1110 shows "th \<in> threads s" |
999 using assms |
1111 using assms |
1000 proof(induct rule:ind) |
1112 proof(induct arbitrary:th cs rule:ind) |
1001 case (Nil) |
1113 case (Nil) |
1002 thus ?case by (auto simp:wq_def) |
1114 thus ?case by (auto simp:wq_def) |
1003 next |
1115 next |
1004 case (Cons s e) |
1116 case (Cons s e) |
1005 interpret vt_e: valid_trace_e s e using Cons by simp |
1117 interpret vt_e: valid_trace_e s e using Cons by simp |
1006 show ?case |
1118 show ?case |
1007 proof(cases e) |
1119 proof(cases e) |
1008 case (Create th' prio') |
1120 case (Create th' prio') |
1009 interpret vt: valid_trace_create s e th' prio' |
1121 interpret vt: valid_trace_create s e th' prio' |
1010 using Create by (unfold_locales, simp) |
1122 using Create by (unfold_locales, simp) |
1011 show ?thesis |
1123 show ?thesis using vt.wq_threads_kept Cons by auto |
1012 using Cons.hyps(2) Cons.prems by auto |
|
1013 next |
1124 next |
1014 case (Exit th') |
1125 case (Exit th') |
1015 interpret vt: valid_trace_exit s e th' |
1126 interpret vt: valid_trace_exit s e th' |
1016 using Exit by (unfold_locales, simp) |
1127 using Exit by (unfold_locales, simp) |
1017 show ?thesis |
1128 show ?thesis using vt.wq_threads_kept Cons by auto |
1018 using Cons.hyps(2) Cons.prems vt.th_not_in_wq by auto |
|
1019 next |
1129 next |
1020 case (P th' cs') |
1130 case (P th' cs') |
1021 interpret vt: valid_trace_p s e th' cs' |
1131 interpret vt: valid_trace_p s e th' cs' |
1022 using P by (unfold_locales, simp) |
1132 using P by (unfold_locales, simp) |
1023 show ?thesis |
1133 show ?thesis using vt.wq_threads_kept Cons by auto |
1024 using Cons.hyps(2) Cons.prems readys_threads |
|
1025 runing_ready vt.is_p vt.runing_th_s vt_e.wq_in_inv |
|
1026 by fastforce |
|
1027 next |
1134 next |
1028 case (V th' cs') |
1135 case (V th' cs') |
1029 interpret vt: valid_trace_v s e th' cs' |
1136 interpret vt: valid_trace_v s e th' cs' |
1030 using V by (unfold_locales, simp) |
1137 using V by (unfold_locales, simp) |
1031 show ?thesis using Cons |
1138 show ?thesis using vt.wq_threads_kept Cons by auto |
1032 using vt.is_v vt.threads_es vt_e.wq_in_inv by blast |
|
1033 next |
1139 next |
1034 case (Set th' prio) |
1140 case (Set th' prio) |
1035 interpret vt: valid_trace_set s e th' prio |
1141 interpret vt: valid_trace_set s e th' prio |
1036 using Set by (unfold_locales, simp) |
1142 using Set by (unfold_locales, simp) |
1037 show ?thesis using Cons.hyps(2) Cons.prems vt.is_set |
1143 show ?thesis using vt.wq_threads_kept Cons by auto |
1038 by (auto simp:wq_def Let_def) |
|
1039 qed |
1144 qed |
1040 qed |
1145 qed |
1041 |
1146 |
1042 section {* RAG and threads *} |
1147 subsection {* RAG and threads *} |
1043 |
1148 |
1044 context valid_trace |
1149 context valid_trace |
1045 begin |
1150 begin |
|
1151 |
|
1152 text {* |
|
1153 As corollaries of @{thm wq_threads}, it is shown in this subsection |
|
1154 that the fields (including both domain |
|
1155 and range) of @{term RAG} are covered by @{term threads}. |
|
1156 *} |
1046 |
1157 |
1047 lemma dm_RAG_threads: |
1158 lemma dm_RAG_threads: |
1048 assumes in_dom: "(Th th) \<in> Domain (RAG s)" |
1159 assumes in_dom: "(Th th) \<in> Domain (RAG s)" |
1049 shows "th \<in> threads s" |
1160 shows "th \<in> threads s" |
1050 proof - |
1161 proof - |