72 surj_h RS surj_f_inv_f]) 1); |
64 surj_h RS surj_f_inv_f]) 1); |
73 qed "h_f_g_eq"; |
65 qed "h_f_g_eq"; |
74 |
66 |
75 (*** extend_set: basic properties ***) |
67 (*** extend_set: basic properties ***) |
76 |
68 |
|
69 Goalw [extend_set_def] "A<=B ==> extend_set h A <= extend_set h B"; |
|
70 by (Blast_tac 1); |
|
71 qed "extend_set_mono"; |
|
72 |
77 Goalw [extend_set_def] |
73 Goalw [extend_set_def] |
78 "z : extend_set h A = (f z : A)"; |
74 "z : extend_set h A = (f z : A)"; |
79 by (force_tac (claset() addIs [h_f_g_eq RS sym], simpset()) 1); |
75 by (force_tac (claset() addIs [h_f_g_eq RS sym], simpset()) 1); |
80 qed "mem_extend_set_iff"; |
76 qed "mem_extend_set_iff"; |
81 AddIffs [mem_extend_set_iff]; |
77 AddIffs [mem_extend_set_iff]; |
82 |
78 |
83 Goal "{s. P (f s)} = extend_set h {s. P s}"; |
79 Goal "{s. P (f s)} = extend_set h {s. P s}"; |
84 by Auto_tac; |
80 by Auto_tac; |
85 qed "Collect_eq_extend_set"; |
81 qed "Collect_eq_extend_set"; |
|
82 |
|
83 Goal "extend_set h {x} = {s. f s = x}"; |
|
84 by Auto_tac; |
|
85 qed "extend_set_sing"; |
86 |
86 |
87 Goalw [extend_set_def, project_set_def] |
87 Goalw [extend_set_def, project_set_def] |
88 "project_set h (extend_set h F) = F"; |
88 "project_set h (extend_set h F) = F"; |
89 by Auto_tac; |
89 by Auto_tac; |
90 qed "extend_set_inverse"; |
90 qed "extend_set_inverse"; |
323 qed "extend_invariant"; |
321 qed "extend_invariant"; |
324 |
322 |
325 (** Safety and project **) |
323 (** Safety and project **) |
326 |
324 |
327 Goalw [constrains_def] |
325 Goalw [constrains_def] |
328 "(F Join project C h G : A co B) = \ |
326 "(project C h F : A co B) = \ |
|
327 \ (F : (C Int extend_set h A) co (extend_set h B) & A <= B)"; |
|
328 by (auto_tac (claset() addSIs [project_act_I], simpset() addsimps [ball_Un])); |
|
329 by (force_tac (claset() addSIs [project_act_I] addSDs [subsetD], simpset()) 1); |
|
330 (*the <== direction*) |
|
331 by (rewtac project_act_def); |
|
332 by (force_tac (claset() addSDs [subsetD], simpset()) 1); |
|
333 qed "project_constrains"; |
|
334 |
|
335 Goalw [stable_def] |
|
336 "(project UNIV h F : stable A) = (F : stable (extend_set h A))"; |
|
337 by (simp_tac (simpset() addsimps [project_constrains]) 1); |
|
338 qed "project_stable"; |
|
339 |
|
340 (*This form's useful with guarantees reasoning*) |
|
341 Goal "(F Join project C h G : A co B) = \ |
329 \ (extend h F Join G : (C Int extend_set h A) co (extend_set h B) & \ |
342 \ (extend h F Join G : (C Int extend_set h A) co (extend_set h B) & \ |
330 \ F : A co B)"; |
343 \ F : A co B)"; |
331 by (auto_tac (claset() addSIs [project_act_I], simpset() addsimps [ball_Un])); |
344 by (simp_tac (simpset() addsimps [Join_constrains, project_constrains]) 1); |
332 by (force_tac (claset() addIs [extend_act_D], simpset()) 1); |
345 by (blast_tac (claset() addIs [extend_constrains RS iffD2 RS constrains_weaken] |
333 by (force_tac (claset() addSIs [project_act_I] addSDs [subsetD], simpset()) 1); |
346 addDs [constrains_imp_subset]) 1); |
334 by (force_tac (claset() addSDs [Id_in_Acts RSN (2,bspec)], simpset()) 1); |
|
335 (*the <== direction*) |
|
336 by (ball_tac 1); |
|
337 by (rewtac project_act_def); |
|
338 by (force_tac (claset() addSDs [subsetD], simpset()) 1); |
|
339 qed "Join_project_constrains"; |
347 qed "Join_project_constrains"; |
340 |
348 |
341 (*The condition is required to prove the left-to-right direction; |
349 (*The condition is required to prove the left-to-right direction; |
342 could weaken it to G : (C Int extend_set h A) co C*) |
350 could weaken it to G : (C Int extend_set h A) co C*) |
343 Goalw [stable_def] |
351 Goalw [stable_def] |
354 by (simp_tac (simpset() addsimps [increasing_def, Join_project_stable]) 1); |
362 by (simp_tac (simpset() addsimps [increasing_def, Join_project_stable]) 1); |
355 by (auto_tac (claset(), |
363 by (auto_tac (claset(), |
356 simpset() addsimps [Join_stable, Collect_eq_extend_set RS sym, |
364 simpset() addsimps [Join_stable, Collect_eq_extend_set RS sym, |
357 extend_stable RS iffD1])); |
365 extend_stable RS iffD1])); |
358 qed "Join_project_increasing"; |
366 qed "Join_project_increasing"; |
359 |
|
360 Goal "(project C h F : A co B) = \ |
|
361 \ (F : (C Int extend_set h A) co (extend_set h B) & A <= B)"; |
|
362 by (cut_inst_tac [("F", "SKIP")] Join_project_constrains 1); |
|
363 by (asm_full_simp_tac (simpset() addsimps [extend_SKIP]) 1); |
|
364 qed "project_constrains"; |
|
365 |
367 |
366 |
368 |
367 (*** Diff, needed for localTo ***) |
369 (*** Diff, needed for localTo ***) |
368 |
370 |
369 (** project versions **) |
371 (** project versions **) |
683 (simpset() addsimps [LeadsTo_def, reachable_extend_eq, |
685 (simpset() addsimps [LeadsTo_def, reachable_extend_eq, |
684 extend_leadsto, extend_set_Int_distrib RS sym]) 1); |
686 extend_leadsto, extend_set_Int_distrib RS sym]) 1); |
685 qed "extend_LeadsTo"; |
687 qed "extend_LeadsTo"; |
686 |
688 |
687 |
689 |
|
690 (** Progress includes safety in the definition of ensures **) |
|
691 |
|
692 (*** Progress for (project C h F) ***) |
|
693 |
|
694 (** transient **) |
|
695 |
|
696 (*Premise is that C includes the domains of all actions that could be the |
|
697 transient one. Could have C=UNIV of course*) |
|
698 Goalw [transient_def] |
|
699 "[| ALL act: Acts F. act ^^ extend_set h A <= - extend_set h A --> \ |
|
700 \ Domain act <= C; \ |
|
701 \ F : transient (extend_set h A) |] \ |
|
702 \ ==> project C h F : transient A"; |
|
703 by (auto_tac (claset() delrules [ballE], |
|
704 simpset() addsimps [Domain_project_act, Int_absorb2])); |
|
705 by (REPEAT (ball_tac 1)); |
|
706 by (auto_tac (claset(), |
|
707 simpset() addsimps [extend_set_def, project_set_def, |
|
708 project_act_def])); |
|
709 by (ALLGOALS Blast_tac); |
|
710 qed "transient_extend_set_imp_project_transient"; |
|
711 |
|
712 |
|
713 (*Converse of the above...it requires a strong assumption about actions |
|
714 being enabled for all possible values of the new variables.*) |
|
715 Goalw [transient_def] |
|
716 "[| project C h F : transient A; \ |
|
717 \ ALL act: Acts F. project_act C h act ^^ A <= - A --> \ |
|
718 \ Domain act <= C \ |
|
719 \ & extend_set h (project_set h (Domain act)) <= Domain act |] \ |
|
720 \ ==> F : transient (extend_set h A)"; |
|
721 by (auto_tac (claset() delrules [ballE], |
|
722 simpset() addsimps [Domain_project_act])); |
|
723 by (ball_tac 1); |
|
724 by (rtac bexI 1); |
|
725 by (assume_tac 2); |
|
726 by Auto_tac; |
|
727 by (eres_inst_tac [("P", "A <= ?B")] rev_mp 1); |
|
728 by (force_tac (claset(), simpset() addsimps [Int_absorb2]) 1); |
|
729 (*The Domain requirement's proved; must prove the Image requirement*) |
|
730 by (res_inst_tac [("y1", "x")] (surj_h RS surjD RS exE) 1); |
|
731 by (res_inst_tac [("y1", "xa")] (surj_h RS surjD RS exE) 1); |
|
732 by Auto_tac; |
|
733 by (thin_tac "A <= ?B" 1); |
|
734 by (force_tac (claset() addSIs [ImageI, project_act_I], simpset()) 1); |
|
735 qed "project_transient_imp_transient_extend_set"; |
|
736 |
|
737 |
|
738 (** ensures **) |
|
739 |
|
740 (*For simplicity, the complicated condition on C is eliminated |
|
741 NOT SURE THIS IS GOOD FOR ANYTHING: CAN'T PROVE LEADSTO THEOREM*) |
|
742 Goal "F : (extend_set h A) ensures (extend_set h B) \ |
|
743 \ ==> project UNIV h F : A ensures B"; |
|
744 by (asm_full_simp_tac |
|
745 (simpset() addsimps [ensures_def, project_constrains, |
|
746 transient_extend_set_imp_project_transient, |
|
747 extend_set_Un_distrib RS sym, |
|
748 extend_set_Diff_distrib RS sym]) 1); |
|
749 by (Blast_tac 1); |
|
750 qed "ensures_extend_set_imp_project_ensures"; |
|
751 |
|
752 (*A super-strong condition: G is not allowed to affect the |
|
753 shared variables at all.*) |
|
754 Goal "[| ALL x. project UNIV h G ~: transient {x}; \ |
|
755 \ F Join project UNIV h G : A ensures B |] \ |
|
756 \ ==> extend h F Join G : (extend_set h A) ensures (extend_set h B)"; |
|
757 by (case_tac "A <= B" 1); |
|
758 by (etac (extend_set_mono RS subset_imp_ensures) 1); |
|
759 by (asm_full_simp_tac |
|
760 (simpset() addsimps [ensures_def, extend_constrains, extend_transient, |
|
761 extend_set_Un_distrib RS sym, |
|
762 extend_set_Diff_distrib RS sym, |
|
763 Join_transient, Join_constrains, |
|
764 project_constrains, Int_absorb1]) 1); |
|
765 (*otherwise PROOF FAILED*) |
|
766 by Auto_tac; |
|
767 by (blast_tac (claset() addIs [transient_strengthen]) 1); |
|
768 qed_spec_mp "Join_project_ensures"; |
|
769 |
|
770 Goal "[| ALL x. project UNIV h G ~: transient {x}; \ |
|
771 \ F Join project UNIV h G : A leadsTo B |] \ |
|
772 \ ==> extend h F Join G : (extend_set h A) leadsTo (extend_set h B)"; |
|
773 by (etac leadsTo_induct 1); |
|
774 by (asm_simp_tac (simpset() addsimps [leadsTo_UN, extend_set_Union]) 3); |
|
775 by (blast_tac (claset() addIs [leadsTo_Trans]) 2); |
|
776 by (blast_tac (claset() addIs [leadsTo_Basis, Join_project_ensures]) 1); |
|
777 qed "Join_project_leadsTo_I"; |
|
778 |
|
779 |
|
780 |
|
781 Goal "F : stable{s} ==> F ~: transient {s}"; |
|
782 by (auto_tac (claset(), |
|
783 simpset() addsimps [FP_def, transient_def, |
|
784 stable_def, constrains_def])); |
|
785 qed "stable_sing_imp_not_transient"; |
|
786 |
|
787 |
688 (** Strong precondition and postcondition; doesn't seem very useful. **) |
788 (** Strong precondition and postcondition; doesn't seem very useful. **) |
689 |
789 |
690 Goal "F : X guarantees Y ==> \ |
790 Goal "F : X guarantees Y ==> \ |
691 \ extend h F : (extend h `` X) guarantees (extend h `` Y)"; |
791 \ extend h F : (extend h `` X) guarantees (extend h `` Y)"; |
692 by (rtac guaranteesI 1); |
792 by (rtac guaranteesI 1); |
715 (*Weak precondition and postcondition; this is the good one! |
815 (*Weak precondition and postcondition; this is the good one! |
716 Not clear that it has a converse [or that we want one!]*) |
816 Not clear that it has a converse [or that we want one!]*) |
717 val [xguary,project,extend] = |
817 val [xguary,project,extend] = |
718 Goal "[| F : X guarantees Y; \ |
818 Goal "[| F : X guarantees Y; \ |
719 \ !!G. extend h F Join G : X' ==> F Join proj G h G : X; \ |
819 \ !!G. extend h F Join G : X' ==> F Join proj G h G : X; \ |
720 \ !!G. F Join proj G h G : Y ==> extend h F Join G : Y' |] \ |
820 \ !!G. [| F Join proj G h G : Y; extend h F Join G : X'; \ |
|
821 \ Disjoint (extend h F) G |] \ |
|
822 \ ==> extend h F Join G : Y' |] \ |
721 \ ==> extend h F : X' guarantees Y'"; |
823 \ ==> extend h F : X' guarantees Y'"; |
722 by (rtac (xguary RS guaranteesD RS extend RS guaranteesI) 1); |
824 by (rtac (xguary RS guaranteesD RS extend RS guaranteesI) 1); |
723 by (etac project 1); |
825 by (etac project 1); |
|
826 by (assume_tac 1); |
|
827 by (assume_tac 1); |
724 qed "project_guarantees"; |
828 qed "project_guarantees"; |
725 |
829 |
726 (** It seems that neither "guarantees" law can be proved from the other. **) |
830 (** It seems that neither "guarantees" law can be proved from the other. **) |
727 |
831 |
728 |
832 |
765 by (stac (project_set_UNIV RS project_extend_Join RS sym) 1); |
869 by (stac (project_set_UNIV RS project_extend_Join RS sym) 1); |
766 by (asm_simp_tac |
870 by (asm_simp_tac |
767 (simpset() addsimps [project_set_UNIV RS project_localTo_I]) 1); |
871 (simpset() addsimps [project_set_UNIV RS project_localTo_I]) 1); |
768 qed "extend_localTo_guar_Increasing"; |
872 qed "extend_localTo_guar_Increasing"; |
769 |
873 |
|
874 |
|
875 (** Guarantees with a leadsTo postcondition **) |
|
876 |
|
877 Goal "[| G : f localTo extend h F; \ |
|
878 \ Disjoint (extend h F) G |] ==> project UNIV h G : stable {x}"; |
|
879 by (asm_full_simp_tac |
|
880 (simpset() addsimps [localTo_imp_stable, |
|
881 extend_set_sing, project_stable]) 1); |
|
882 qed "localTo_imp_project_stable"; |
|
883 |
|
884 |
|
885 Goal "F : (A co A') guarantees (B leadsTo B') \ |
|
886 \ ==> extend h F : ((extend_set h A) co (extend_set h A')) \ |
|
887 \ Int (f localTo (extend h F)) \ |
|
888 \ guarantees ((extend_set h B) leadsTo (extend_set h B'))"; |
|
889 by (etac project_guarantees 1); |
|
890 (*the safety precondition*) |
|
891 by (stac (project_set_UNIV RS project_extend_Join RS sym) 1); |
|
892 by (asm_full_simp_tac |
|
893 (simpset() addsimps [project_constrains, Join_constrains, |
|
894 extend_constrains]) 1); |
|
895 by (fast_tac (claset() addDs [constrains_imp_subset]) 1); |
|
896 (*the liveness postcondition*) |
|
897 by (rtac Join_project_leadsTo_I 1); |
|
898 by Auto_tac; |
|
899 by (asm_full_simp_tac |
|
900 (simpset() addsimps [Join_localTo, self_localTo, |
|
901 localTo_imp_project_stable, stable_sing_imp_not_transient]) 1); |
|
902 qed "extend_co_guar_leadsTo"; |
|
903 |
|
904 |
770 Close_locale "Extend"; |
905 Close_locale "Extend"; |
771 |
906 |
772 (*Close_locale should do this! |
907 (*Close_locale should do this! |
773 Delsimps [f_h_eq, extend_set_inverse, f_image_extend_set, extend_act_inverse, |
908 Delsimps [f_h_eq, extend_set_inverse, f_image_extend_set, extend_act_inverse, |
774 extend_act_Image]; |
909 extend_act_Image]; |