113 (* the predicate S describes the states of the implementation. |
113 (* the predicate S describes the states of the implementation. |
114 slight simplification: two "histState" parameters instead of a |
114 slight simplification: two "histState" parameters instead of a |
115 (one- or two-element) set. |
115 (one- or two-element) set. |
116 NB: The second conjunct of the definition in the paper is taken care of by |
116 NB: The second conjunct of the definition in the paper is taken care of by |
117 the type definitions. The last conjunct is asserted separately as the memory |
117 the type definitions. The last conjunct is asserted separately as the memory |
118 invariant MemInv, proved in Memory.ML. *) |
118 invariant MemInv, proved in Memory.thy. *) |
119 S :: "histType => bool => bool => bool => mClkState => rpcState => histState => histState => PrIds => stpred" |
119 S :: "histType => bool => bool => bool => mClkState => rpcState => histState => histState => PrIds => stpred" |
120 "S rmhist ecalling ccalling rcalling cs rs hs1 hs2 p == PRED |
120 "S rmhist ecalling ccalling rcalling cs rs hs1 hs2 p == PRED |
121 Calling memCh p = #ecalling |
121 Calling memCh p = #ecalling |
122 & Calling crCh p = #ccalling |
122 & Calling crCh p = #ccalling |
123 & (#ccalling --> arg<crCh!p> = MClkRelayArg<arg<memCh!p>>) |
123 & (#ccalling --> arg<crCh!p> = MClkRelayArg<arg<memCh!p>>) |
175 (mm!l, rtrner rmCh!p, ires!p))" |
175 (mm!l, rtrner rmCh!p, ires!p))" |
176 |
176 |
177 (* |
177 (* |
178 The main theorem is theorem "Implementation" at the end of this file, |
178 The main theorem is theorem "Implementation" at the end of this file, |
179 which shows that the composition of a reliable memory, an RPC component, and |
179 which shows that the composition of a reliable memory, an RPC component, and |
180 a memory clerk implements an unreliable memory. The files "MIsafe.ML" and |
180 a memory clerk implements an unreliable memory. The files "MIsafe.thy" and |
181 "MIlive.ML" contain lower-level lemmas for the safety and liveness parts. |
181 "MIlive.thy" contain lower-level lemmas for the safety and liveness parts. |
182 |
182 |
183 Steps are (roughly) numbered as in the hand proof. |
183 Steps are (roughly) numbered as in the hand proof. |
184 *) |
184 *) |
185 |
185 |
186 (* --------------------------- automatic prover --------------------------- *) |
186 (* --------------------------- automatic prover --------------------------- *) |
187 |
187 |
188 declare if_weak_cong [cong del] |
188 declare if_weak_cong [cong del] |
189 |
189 |
190 ML {* val MI_css = (claset(), simpset()) *} |
190 ML {* val MI_css = (@{claset}, @{simpset}) *} |
191 |
191 |
192 (* A more aggressive variant that tries to solve subgoals by assumption |
192 (* A more aggressive variant that tries to solve subgoals by assumption |
193 or contradiction during the simplification. |
193 or contradiction during the simplification. |
194 THIS IS UNSAFE, BECAUSE IT DOESN'T RECORD THE CHOICES!! |
194 THIS IS UNSAFE, BECAUSE IT DOESN'T RECORD THE CHOICES!! |
195 (but it can be a lot faster than MI_css) |
195 (but it can be a lot faster than MI_css) |
760 |
760 |
761 (* Frequently needed abbreviation: distinguish between idling and non-idling |
761 (* Frequently needed abbreviation: distinguish between idling and non-idling |
762 steps of the implementation, and try to solve the idling case by simplification |
762 steps of the implementation, and try to solve the idling case by simplification |
763 *) |
763 *) |
764 ML {* |
764 ML {* |
765 local |
765 fun split_idle_tac ss simps i = |
766 val actionI = thm "actionI"; |
766 EVERY [TRY (rtac @{thm actionI} i), |
767 val action_rews = thms "action_rews"; |
|
768 val Step1_4_7 = thm "Step1_4_7"; |
|
769 in |
|
770 fun split_idle_tac simps i = |
|
771 EVERY [TRY (rtac actionI i), |
|
772 case_tac "(s,t) |= unchanged (e p, c p, r p, m p, rmhist!p)" i, |
767 case_tac "(s,t) |= unchanged (e p, c p, r p, m p, rmhist!p)" i, |
773 rewrite_goals_tac action_rews, |
768 rewrite_goals_tac @{thms action_rews}, |
774 forward_tac [temp_use Step1_4_7] i, |
769 forward_tac [temp_use @{thm Step1_4_7}] i, |
775 asm_full_simp_tac (simpset() addsimps simps) i |
770 asm_full_simp_tac (ss addsimps simps) i |
776 ] |
771 ] |
777 end |
|
778 *} |
772 *} |
779 (* ---------------------------------------------------------------------- |
773 (* ---------------------------------------------------------------------- |
780 Combine steps 1.2 and 1.4 to prove that the implementation satisfies |
774 Combine steps 1.2 and 1.4 to prove that the implementation satisfies |
781 the specification's next-state relation. |
775 the specification's next-state relation. |
782 *) |
776 *) |
784 (* Steps that leave all variables unchanged are safe, so I may assume |
778 (* Steps that leave all variables unchanged are safe, so I may assume |
785 that some variable changes in the proof that a step is safe. *) |
779 that some variable changes in the proof that a step is safe. *) |
786 lemma unchanged_safe: "|- (~unchanged (e p, c p, r p, m p, rmhist!p) |
780 lemma unchanged_safe: "|- (~unchanged (e p, c p, r p, m p, rmhist!p) |
787 --> [UNext memCh mm (resbar rmhist) p]_(rtrner memCh!p, resbar rmhist!p)) |
781 --> [UNext memCh mm (resbar rmhist) p]_(rtrner memCh!p, resbar rmhist!p)) |
788 --> [UNext memCh mm (resbar rmhist) p]_(rtrner memCh!p, resbar rmhist!p)" |
782 --> [UNext memCh mm (resbar rmhist) p]_(rtrner memCh!p, resbar rmhist!p)" |
789 apply (tactic {* split_idle_tac [thm "square_def"] 1 *}) |
783 apply (tactic {* split_idle_tac @{simpset} [thm "square_def"] 1 *}) |
790 apply force |
784 apply force |
791 done |
785 done |
792 (* turn into (unsafe, looping!) introduction rule *) |
786 (* turn into (unsafe, looping!) introduction rule *) |
793 lemmas unchanged_safeI = impI [THEN unchanged_safe [action_use], standard] |
787 lemmas unchanged_safeI = impI [THEN unchanged_safe [action_use], standard] |
794 |
788 |
856 |
850 |
857 (* ------------------------------ State S1 ------------------------------ *) |
851 (* ------------------------------ State S1 ------------------------------ *) |
858 |
852 |
859 lemma S1_successors: "|- $S1 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
853 lemma S1_successors: "|- $S1 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
860 --> (S1 rmhist p)$ | (S2 rmhist p)$" |
854 --> (S1 rmhist p)$ | (S2 rmhist p)$" |
861 apply (tactic "split_idle_tac [] 1") |
855 apply (tactic "split_idle_tac @{simpset} [] 1") |
862 apply (auto dest!: Step1_2_1 [temp_use]) |
856 apply (auto dest!: Step1_2_1 [temp_use]) |
863 done |
857 done |
864 |
858 |
865 (* Show that the implementation can satisfy the high-level fairness requirements |
859 (* Show that the implementation can satisfy the high-level fairness requirements |
866 by entering the state S1 infinitely often. |
860 by entering the state S1 infinitely often. |
890 |
884 |
891 (* ------------------------------ State S2 ------------------------------ *) |
885 (* ------------------------------ State S2 ------------------------------ *) |
892 |
886 |
893 lemma S2_successors: "|- $S2 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
887 lemma S2_successors: "|- $S2 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
894 --> (S2 rmhist p)$ | (S3 rmhist p)$" |
888 --> (S2 rmhist p)$ | (S3 rmhist p)$" |
895 apply (tactic "split_idle_tac [] 1") |
889 apply (tactic "split_idle_tac @{simpset} [] 1") |
896 apply (auto dest!: Step1_2_2 [temp_use]) |
890 apply (auto dest!: Step1_2_2 [temp_use]) |
897 done |
891 done |
898 |
892 |
899 lemma S2MClkFwd_successors: "|- ($S2 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
893 lemma S2MClkFwd_successors: "|- ($S2 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
900 & <MClkFwd memCh crCh cst p>_(c p) |
894 & <MClkFwd memCh crCh cst p>_(c p) |
916 |
910 |
917 (* ------------------------------ State S3 ------------------------------ *) |
911 (* ------------------------------ State S3 ------------------------------ *) |
918 |
912 |
919 lemma S3_successors: "|- $S3 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
913 lemma S3_successors: "|- $S3 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
920 --> (S3 rmhist p)$ | (S4 rmhist p | S6 rmhist p)$" |
914 --> (S3 rmhist p)$ | (S4 rmhist p | S6 rmhist p)$" |
921 apply (tactic "split_idle_tac [] 1") |
915 apply (tactic "split_idle_tac @{simpset} [] 1") |
922 apply (auto dest!: Step1_2_3 [temp_use]) |
916 apply (auto dest!: Step1_2_3 [temp_use]) |
923 done |
917 done |
924 |
918 |
925 lemma S3RPC_successors: "|- ($S3 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
919 lemma S3RPC_successors: "|- ($S3 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
926 & <RPCNext crCh rmCh rst p>_(r p) |
920 & <RPCNext crCh rmCh rst p>_(r p) |
944 (* ------------- State S4 -------------------------------------------------- *) |
938 (* ------------- State S4 -------------------------------------------------- *) |
945 |
939 |
946 lemma S4_successors: "|- $S4 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
940 lemma S4_successors: "|- $S4 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
947 & (ALL l. $MemInv mm l) |
941 & (ALL l. $MemInv mm l) |
948 --> (S4 rmhist p)$ | (S5 rmhist p)$" |
942 --> (S4 rmhist p)$ | (S5 rmhist p)$" |
949 apply (tactic "split_idle_tac [] 1") |
943 apply (tactic "split_idle_tac @{simpset} [] 1") |
950 apply (auto dest!: Step1_2_4 [temp_use]) |
944 apply (auto dest!: Step1_2_4 [temp_use]) |
951 done |
945 done |
952 |
946 |
953 (* --------- State S4a: S4 /\ (ires p = NotAResult) ------------------------ *) |
947 (* --------- State S4a: S4 /\ (ires p = NotAResult) ------------------------ *) |
954 |
948 |
955 lemma S4a_successors: "|- $(S4 rmhist p & ires!p = #NotAResult) |
949 lemma S4a_successors: "|- $(S4 rmhist p & ires!p = #NotAResult) |
956 & ImpNext p & [HNext rmhist p]_(c p,r p,m p,rmhist!p) & (ALL l. $MemInv mm l) |
950 & ImpNext p & [HNext rmhist p]_(c p,r p,m p,rmhist!p) & (ALL l. $MemInv mm l) |
957 --> (S4 rmhist p & ires!p = #NotAResult)$ |
951 --> (S4 rmhist p & ires!p = #NotAResult)$ |
958 | ((S4 rmhist p & ires!p ~= #NotAResult) | S5 rmhist p)$" |
952 | ((S4 rmhist p & ires!p ~= #NotAResult) | S5 rmhist p)$" |
959 apply (tactic {* split_idle_tac [thm "m_def"] 1 *}) |
953 apply (tactic {* split_idle_tac @{simpset} [thm "m_def"] 1 *}) |
960 apply (auto dest!: Step1_2_4 [temp_use]) |
954 apply (auto dest!: Step1_2_4 [temp_use]) |
961 done |
955 done |
962 |
956 |
963 lemma S4aRNext_successors: "|- ($(S4 rmhist p & ires!p = #NotAResult) |
957 lemma S4aRNext_successors: "|- ($(S4 rmhist p & ires!p = #NotAResult) |
964 & ImpNext p & [HNext rmhist p]_(c p,r p,m p,rmhist!p) & (ALL l. $MemInv mm l)) |
958 & ImpNext p & [HNext rmhist p]_(c p,r p,m p,rmhist!p) & (ALL l. $MemInv mm l)) |
985 (* ---------- State S4b: S4 /\ (ires p # NotAResult) --------------------------- *) |
979 (* ---------- State S4b: S4 /\ (ires p # NotAResult) --------------------------- *) |
986 |
980 |
987 lemma S4b_successors: "|- $(S4 rmhist p & ires!p ~= #NotAResult) |
981 lemma S4b_successors: "|- $(S4 rmhist p & ires!p ~= #NotAResult) |
988 & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) & (ALL l. $MemInv mm l) |
982 & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) & (ALL l. $MemInv mm l) |
989 --> (S4 rmhist p & ires!p ~= #NotAResult)$ | (S5 rmhist p)$" |
983 --> (S4 rmhist p & ires!p ~= #NotAResult)$ | (S5 rmhist p)$" |
990 apply (tactic {* split_idle_tac [thm "m_def"] 1 *}) |
984 apply (tactic {* split_idle_tac @{simpset} [thm "m_def"] 1 *}) |
991 apply (auto dest!: WriteResult [temp_use] Step1_2_4 [temp_use] ReadResult [temp_use]) |
985 apply (auto dest!: WriteResult [temp_use] Step1_2_4 [temp_use] ReadResult [temp_use]) |
992 done |
986 done |
993 |
987 |
994 lemma S4bReturn_successors: "|- ($(S4 rmhist p & ires!p ~= #NotAResult) |
988 lemma S4bReturn_successors: "|- ($(S4 rmhist p & ires!p ~= #NotAResult) |
995 & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
989 & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
1014 |
1008 |
1015 (* ------------------------------ State S5 ------------------------------ *) |
1009 (* ------------------------------ State S5 ------------------------------ *) |
1016 |
1010 |
1017 lemma S5_successors: "|- $S5 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
1011 lemma S5_successors: "|- $S5 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
1018 --> (S5 rmhist p)$ | (S6 rmhist p)$" |
1012 --> (S5 rmhist p)$ | (S6 rmhist p)$" |
1019 apply (tactic "split_idle_tac [] 1") |
1013 apply (tactic "split_idle_tac @{simpset} [] 1") |
1020 apply (auto dest!: Step1_2_5 [temp_use]) |
1014 apply (auto dest!: Step1_2_5 [temp_use]) |
1021 done |
1015 done |
1022 |
1016 |
1023 lemma S5RPC_successors: "|- ($S5 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
1017 lemma S5RPC_successors: "|- ($S5 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
1024 & <RPCNext crCh rmCh rst p>_(r p) |
1018 & <RPCNext crCh rmCh rst p>_(r p) |
1040 |
1034 |
1041 (* ------------------------------ State S6 ------------------------------ *) |
1035 (* ------------------------------ State S6 ------------------------------ *) |
1042 |
1036 |
1043 lemma S6_successors: "|- $S6 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
1037 lemma S6_successors: "|- $S6 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p) |
1044 --> (S1 rmhist p)$ | (S3 rmhist p)$ | (S6 rmhist p)$" |
1038 --> (S1 rmhist p)$ | (S3 rmhist p)$ | (S6 rmhist p)$" |
1045 apply (tactic "split_idle_tac [] 1") |
1039 apply (tactic "split_idle_tac @{simpset} [] 1") |
1046 apply (auto dest!: Step1_2_6 [temp_use]) |
1040 apply (auto dest!: Step1_2_6 [temp_use]) |
1047 done |
1041 done |
1048 |
1042 |
1049 lemma S6MClkReply_successors: |
1043 lemma S6MClkReply_successors: |
1050 "|- ($S6 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
1044 "|- ($S6 rmhist p & ImpNext p & [HNext rmhist p]_(c p,r p,m p, rmhist!p)) |
1255 & $ImpInv rmhist p |
1249 & $ImpInv rmhist p |
1256 --> (S4 rmhist p)$ & unchanged (e p, c p, r p, rmhist!p)" |
1250 --> (S4 rmhist p)$ & unchanged (e p, c p, r p, rmhist!p)" |
1257 apply clarsimp |
1251 apply clarsimp |
1258 apply (drule WriteS4 [action_use]) |
1252 apply (drule WriteS4 [action_use]) |
1259 apply assumption |
1253 apply assumption |
1260 apply (tactic "split_idle_tac [] 1") |
1254 apply (tactic "split_idle_tac @{simpset} [] 1") |
1261 apply (auto simp: ImpNext_def dest!: S4EnvUnch [temp_use] S4ClerkUnch [temp_use] |
1255 apply (auto simp: ImpNext_def dest!: S4EnvUnch [temp_use] S4ClerkUnch [temp_use] |
1262 S4RPCUnch [temp_use]) |
1256 S4RPCUnch [temp_use]) |
1263 apply (auto simp: square_def dest: S4Write [temp_use]) |
1257 apply (auto simp: square_def dest: S4Write [temp_use]) |
1264 done |
1258 done |
1265 |
1259 |