368 \<equiv> let (oref,xf) = if stat then (Stat C,id) |
368 \<equiv> let (oref,xf) = if stat then (Stat C,id) |
369 else (Heap (the_Addr a'),np a'); |
369 else (Heap (the_Addr a'),np a'); |
370 n = Inl (fn,C); |
370 n = Inl (fn,C); |
371 f = (\<lambda>v. supd (upd_gobj oref n v)) |
371 f = (\<lambda>v. supd (upd_gobj oref n v)) |
372 in ((the (values (the (globs (store s) oref)) n),f),abupd xf s)" |
372 in ((the (values (the (globs (store s) oref)) n),f),abupd xf s)" |
373 |
373 (* |
|
374 "fvar C stat fn a' s |
|
375 \<equiv> let (oref,xf) = if stat then (Stat C,id) |
|
376 else (Heap (the_Addr a'),np a'); |
|
377 n = Inl (fn,C); |
|
378 f = (\<lambda>v. supd (upd_gobj oref n v)) |
|
379 in ((the (values (the (globs (store s) oref)) n),f),abupd xf s)" |
|
380 *) |
374 avar :: "prog \<Rightarrow> val \<Rightarrow> val \<Rightarrow> state \<Rightarrow> vvar \<times> state" |
381 avar :: "prog \<Rightarrow> val \<Rightarrow> val \<Rightarrow> state \<Rightarrow> vvar \<times> state" |
375 "avar G i' a' s |
382 "avar G i' a' s |
376 \<equiv> let oref = Heap (the_Addr a'); |
383 \<equiv> let oref = Heap (the_Addr a'); |
377 i = the_Intg i'; |
384 i = the_Intg i'; |
378 n = Inr i; |
385 n = Inr i; |
410 s)" |
417 s)" |
411 apply (unfold avar_def) |
418 apply (unfold avar_def) |
412 apply (simp (no_asm) add: Let_def split_beta) |
419 apply (simp (no_asm) add: Let_def split_beta) |
413 done |
420 done |
414 |
421 |
415 |
422 constdefs |
|
423 check_field_access:: |
|
424 "prog \<Rightarrow> qtname \<Rightarrow> qtname \<Rightarrow> vname \<Rightarrow> bool \<Rightarrow> val \<Rightarrow> state \<Rightarrow> state" |
|
425 "check_field_access G accC statDeclC fn stat a' s |
|
426 \<equiv> let oref = if stat then Stat statDeclC |
|
427 else Heap (the_Addr a'); |
|
428 dynC = case oref of |
|
429 Heap a \<Rightarrow> obj_class (the (globs (store s) oref)) |
|
430 | Stat C \<Rightarrow> C; |
|
431 f = (the (table_of (DeclConcepts.fields G dynC) (fn,statDeclC))) |
|
432 in abupd |
|
433 (error_if (\<not> G\<turnstile>Field fn (statDeclC,f) in dynC dyn_accessible_from accC) |
|
434 AccessViolation) |
|
435 s" |
|
436 |
|
437 constdefs |
|
438 check_method_access:: |
|
439 "prog \<Rightarrow> qtname \<Rightarrow> ref_ty \<Rightarrow> inv_mode \<Rightarrow> sig \<Rightarrow> val \<Rightarrow> state \<Rightarrow> state" |
|
440 "check_method_access G accC statT mode sig a' s |
|
441 \<equiv> let invC = invocation_class mode (store s) a' statT; |
|
442 dynM = the (dynlookup G statT invC sig) |
|
443 in abupd |
|
444 (error_if (\<not> G\<turnstile>Methd sig dynM in invC dyn_accessible_from accC) |
|
445 AccessViolation) |
|
446 s" |
|
447 |
416 section "evaluation judgments" |
448 section "evaluation judgments" |
417 |
449 |
418 consts |
450 consts |
419 eval :: "prog \<Rightarrow> (state \<times> term \<times> vals \<times> state) set" |
451 eval :: "prog \<Rightarrow> (state \<times> term \<times> vals \<times> state) set" |
420 halloc:: "prog \<Rightarrow> (state \<times> obj_tag \<times> loc \<times> state) set" |
452 halloc:: "prog \<Rightarrow> (state \<times> obj_tag \<times> loc \<times> state) set" |
550 else (G\<turnstile>Norm (init_class_obj G C s0) |
582 else (G\<turnstile>Norm (init_class_obj G C s0) |
551 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
583 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
552 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
584 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
553 \<Longrightarrow> |
585 \<Longrightarrow> |
554 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
586 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
555 |
587 (* This class initialisation rule is a little bit inaccurate. Look at the |
|
588 exact sequence: |
|
589 1. The current class object (the static fields) are initialised |
|
590 (init_class_obj) |
|
591 2. Then the superclasses are initialised |
|
592 3. The static initialiser of the current class is invoked |
|
593 More precisely we should expect another ordering, namely 2 1 3. |
|
594 But we can't just naively toggle 1 and 2. By calling init_class_obj |
|
595 before initialising the superclasses we also implicitly record that |
|
596 we have started to initialise the current class (by setting an |
|
597 value for the class object). This becomes |
|
598 crucial for the completeness proof of the axiomatic semantics |
|
599 (AxCompl.thy). Static initialisation requires an induction on the number |
|
600 of classes not yet initialised (or to be more precise, classes where the |
|
601 initialisation has not yet begun). |
|
602 So we could first assign a dummy value to the class before |
|
603 superclass initialisation and afterwards set the correct values. |
|
604 But as long as we don't take memory overflow into account |
|
605 when allocating class objects, and don't model definite assignment in |
|
606 the static initialisers, we can leave things as they are for convenience. |
|
607 *) |
556 (* evaluation of expressions *) |
608 (* evaluation of expressions *) |
557 |
609 |
558 (* cf. 15.8.1, 12.4.1 *) |
610 (* cf. 15.8.1, 12.4.1 *) |
559 NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
611 NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
560 G\<turnstile> s1 \<midarrow>halloc (CInst C)\<succ>a\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
612 G\<turnstile> s1 \<midarrow>halloc (CInst C)\<succ>a\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
600 |
652 |
601 (* cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5 *) |
653 (* cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5 *) |
602 Call: |
654 Call: |
603 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
655 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
604 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
656 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
605 G\<turnstile>init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2 |
657 s3=init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2; |
606 \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s3\<rbrakk> |
658 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
|
659 G\<turnstile>s3' \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s4\<rbrakk> |
607 \<Longrightarrow> |
660 \<Longrightarrow> |
608 G\<turnstile>Norm s0 \<midarrow>{statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s3)" |
661 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s4)" |
|
662 (* The accessibility check is after init_lvars, to keep it simple. Init_lvars |
|
663 already tests for the absence of a null-pointer reference in case of an |
|
664 instance method invocation |
|
665 *) |
609 |
666 |
610 Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
667 Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
611 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
668 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
612 |
669 |
613 (* cf. 14.15, 12.4.1 *) |
670 (* cf. 14.15, 12.4.1 *) |
618 |
675 |
619 (* cf. 15.13.1, 15.7.2 *) |
676 (* cf. 15.13.1, 15.7.2 *) |
620 LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
677 LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
621 |
678 |
622 (* cf. 15.10.1, 12.4.1 *) |
679 (* cf. 15.10.1, 12.4.1 *) |
623 FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
680 FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
624 (v,s2') = fvar C stat fn a s2\<rbrakk> \<Longrightarrow> |
681 (v,s2') = fvar statDeclC stat fn a s2; |
625 G\<turnstile>Norm s0 \<midarrow>{C,stat}e..fn=\<succ>v\<rightarrow> s2'" |
682 s3 = check_field_access G accC statDeclC fn stat a s2' \<rbrakk> \<Longrightarrow> |
|
683 G\<turnstile>Norm s0 \<midarrow>{accC,statDeclC,stat}e..fn=\<succ>v\<rightarrow> s3" |
|
684 (* The accessibility check is after fvar, to keep it simple. Fvar already |
|
685 tests for the absence of a null-pointer reference in case of an instance |
|
686 field |
|
687 *) |
626 |
688 |
627 (* cf. 15.12.1, 15.25.1 *) |
689 (* cf. 15.12.1, 15.25.1 *) |
628 AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
690 AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
629 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
691 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
630 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
692 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
686 simpset_ref() := simpset() delloop "split_all_tac" |
748 simpset_ref() := simpset() delloop "split_all_tac" |
687 *} |
749 *} |
688 inductive_cases eval_cases: "G\<turnstile>s \<midarrow>t\<succ>\<rightarrow> vs'" |
750 inductive_cases eval_cases: "G\<turnstile>s \<midarrow>t\<succ>\<rightarrow> vs'" |
689 |
751 |
690 inductive_cases eval_elim_cases: |
752 inductive_cases eval_elim_cases: |
691 "G\<turnstile>(Some xc,s) \<midarrow>t \<succ>\<rightarrow> vs'" |
753 "G\<turnstile>(Some xc,s) \<midarrow>t \<succ>\<rightarrow> vs'" |
692 "G\<turnstile>Norm s \<midarrow>In1r Skip \<succ>\<rightarrow> xs'" |
754 "G\<turnstile>Norm s \<midarrow>In1r Skip \<succ>\<rightarrow> xs'" |
693 "G\<turnstile>Norm s \<midarrow>In1r (Do j) \<succ>\<rightarrow> xs'" |
755 "G\<turnstile>Norm s \<midarrow>In1r (Do j) \<succ>\<rightarrow> xs'" |
694 "G\<turnstile>Norm s \<midarrow>In1r (l\<bullet> c) \<succ>\<rightarrow> xs'" |
756 "G\<turnstile>Norm s \<midarrow>In1r (l\<bullet> c) \<succ>\<rightarrow> xs'" |
695 "G\<turnstile>Norm s \<midarrow>In3 ([]) \<succ>\<rightarrow> vs'" |
757 "G\<turnstile>Norm s \<midarrow>In3 ([]) \<succ>\<rightarrow> vs'" |
696 "G\<turnstile>Norm s \<midarrow>In3 (e#es) \<succ>\<rightarrow> vs'" |
758 "G\<turnstile>Norm s \<midarrow>In3 (e#es) \<succ>\<rightarrow> vs'" |
697 "G\<turnstile>Norm s \<midarrow>In1l (Lit w) \<succ>\<rightarrow> vs'" |
759 "G\<turnstile>Norm s \<midarrow>In1l (Lit w) \<succ>\<rightarrow> vs'" |
698 "G\<turnstile>Norm s \<midarrow>In2 (LVar vn) \<succ>\<rightarrow> vs'" |
760 "G\<turnstile>Norm s \<midarrow>In2 (LVar vn) \<succ>\<rightarrow> vs'" |
699 "G\<turnstile>Norm s \<midarrow>In1l (Cast T e) \<succ>\<rightarrow> vs'" |
761 "G\<turnstile>Norm s \<midarrow>In1l (Cast T e) \<succ>\<rightarrow> vs'" |
700 "G\<turnstile>Norm s \<midarrow>In1l (e InstOf T) \<succ>\<rightarrow> vs'" |
762 "G\<turnstile>Norm s \<midarrow>In1l (e InstOf T) \<succ>\<rightarrow> vs'" |
701 "G\<turnstile>Norm s \<midarrow>In1l (Super) \<succ>\<rightarrow> vs'" |
763 "G\<turnstile>Norm s \<midarrow>In1l (Super) \<succ>\<rightarrow> vs'" |
702 "G\<turnstile>Norm s \<midarrow>In1l (Acc va) \<succ>\<rightarrow> vs'" |
764 "G\<turnstile>Norm s \<midarrow>In1l (Acc va) \<succ>\<rightarrow> vs'" |
703 "G\<turnstile>Norm s \<midarrow>In1r (Expr e) \<succ>\<rightarrow> xs'" |
765 "G\<turnstile>Norm s \<midarrow>In1r (Expr e) \<succ>\<rightarrow> xs'" |
704 "G\<turnstile>Norm s \<midarrow>In1r (c1;; c2) \<succ>\<rightarrow> xs'" |
766 "G\<turnstile>Norm s \<midarrow>In1r (c1;; c2) \<succ>\<rightarrow> xs'" |
705 "G\<turnstile>Norm s \<midarrow>In1l (Methd C sig) \<succ>\<rightarrow> xs'" |
767 "G\<turnstile>Norm s \<midarrow>In1l (Methd C sig) \<succ>\<rightarrow> xs'" |
706 "G\<turnstile>Norm s \<midarrow>In1l (Body D c) \<succ>\<rightarrow> xs'" |
768 "G\<turnstile>Norm s \<midarrow>In1l (Body D c) \<succ>\<rightarrow> xs'" |
707 "G\<turnstile>Norm s \<midarrow>In1l (e0 ? e1 : e2) \<succ>\<rightarrow> vs'" |
769 "G\<turnstile>Norm s \<midarrow>In1l (e0 ? e1 : e2) \<succ>\<rightarrow> vs'" |
708 "G\<turnstile>Norm s \<midarrow>In1r (If(e) c1 Else c2) \<succ>\<rightarrow> xs'" |
770 "G\<turnstile>Norm s \<midarrow>In1r (If(e) c1 Else c2) \<succ>\<rightarrow> xs'" |
709 "G\<turnstile>Norm s \<midarrow>In1r (l\<bullet> While(e) c) \<succ>\<rightarrow> xs'" |
771 "G\<turnstile>Norm s \<midarrow>In1r (l\<bullet> While(e) c) \<succ>\<rightarrow> xs'" |
710 "G\<turnstile>Norm s \<midarrow>In1r (c1 Finally c2) \<succ>\<rightarrow> xs'" |
772 "G\<turnstile>Norm s \<midarrow>In1r (c1 Finally c2) \<succ>\<rightarrow> xs'" |
711 "G\<turnstile>Norm s \<midarrow>In1r (Throw e) \<succ>\<rightarrow> xs'" |
773 "G\<turnstile>Norm s \<midarrow>In1r (Throw e) \<succ>\<rightarrow> xs'" |
712 "G\<turnstile>Norm s \<midarrow>In1l (NewC C) \<succ>\<rightarrow> vs'" |
774 "G\<turnstile>Norm s \<midarrow>In1l (NewC C) \<succ>\<rightarrow> vs'" |
713 "G\<turnstile>Norm s \<midarrow>In1l (New T[e]) \<succ>\<rightarrow> vs'" |
775 "G\<turnstile>Norm s \<midarrow>In1l (New T[e]) \<succ>\<rightarrow> vs'" |
714 "G\<turnstile>Norm s \<midarrow>In1l (Ass va e) \<succ>\<rightarrow> vs'" |
776 "G\<turnstile>Norm s \<midarrow>In1l (Ass va e) \<succ>\<rightarrow> vs'" |
715 "G\<turnstile>Norm s \<midarrow>In1r (Try c1 Catch(tn vn) c2) \<succ>\<rightarrow> xs'" |
777 "G\<turnstile>Norm s \<midarrow>In1r (Try c1 Catch(tn vn) c2) \<succ>\<rightarrow> xs'" |
716 "G\<turnstile>Norm s \<midarrow>In2 ({C,stat}e..fn) \<succ>\<rightarrow> vs'" |
778 "G\<turnstile>Norm s \<midarrow>In2 ({accC,statDeclC,stat}e..fn) \<succ>\<rightarrow> vs'" |
717 "G\<turnstile>Norm s \<midarrow>In2 (e1.[e2]) \<succ>\<rightarrow> vs'" |
779 "G\<turnstile>Norm s \<midarrow>In2 (e1.[e2]) \<succ>\<rightarrow> vs'" |
718 "G\<turnstile>Norm s \<midarrow>In1l ({statT,mode}e\<cdot>mn({pT}p)) \<succ>\<rightarrow> vs'" |
780 "G\<turnstile>Norm s \<midarrow>In1l ({accC,statT,mode}e\<cdot>mn({pT}p)) \<succ>\<rightarrow> vs'" |
719 "G\<turnstile>Norm s \<midarrow>In1r (Init C) \<succ>\<rightarrow> xs'" |
781 "G\<turnstile>Norm s \<midarrow>In1r (Init C) \<succ>\<rightarrow> xs'" |
720 declare not_None_eq [simp] (* IntDef.Zero_def [simp] *) |
782 declare not_None_eq [simp] (* IntDef.Zero_def [simp] *) |
721 declare split_paired_All [simp] split_paired_Ex [simp] |
783 declare split_paired_All [simp] split_paired_Ex [simp] |
722 ML_setup {* |
784 ML_setup {* |
723 simpset_ref() := simpset() addloop ("split_all_tac", split_all_tac) |
785 simpset_ref() := simpset() addloop ("split_all_tac", split_all_tac) |
724 *} |
786 *} |
849 |
911 |
850 lemma MethdI: "G\<turnstile>s \<midarrow>body G C sig-\<succ>v\<rightarrow> s' \<Longrightarrow> G\<turnstile>s \<midarrow>Methd C sig-\<succ>v\<rightarrow> s'" |
912 lemma MethdI: "G\<turnstile>s \<midarrow>body G C sig-\<succ>v\<rightarrow> s' \<Longrightarrow> G\<turnstile>s \<midarrow>Methd C sig-\<succ>v\<rightarrow> s'" |
851 apply (case_tac "s", case_tac "a = None") |
913 apply (case_tac "s", case_tac "a = None") |
852 by (auto intro!: eval.Methd) |
914 by (auto intro!: eval.Methd) |
853 |
915 |
854 lemma eval_Call: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>ps\<doteq>\<succ>pvs\<rightarrow> s2; |
916 lemma eval_Call: |
855 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
917 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>ps\<doteq>\<succ>pvs\<rightarrow> s2; |
856 G\<turnstile>init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' pvs s2 |
918 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
857 \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ> v\<rightarrow> s3; |
919 s3 = init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' pvs s2; |
858 s3' = restore_lvars s2 s3\<rbrakk> \<Longrightarrow> |
920 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
859 G\<turnstile>Norm s0 \<midarrow>{statT,mode}e\<cdot>mn({pTs}ps)-\<succ>v\<rightarrow> s3'" |
921 G\<turnstile>s3'\<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ> v\<rightarrow> s4; |
|
922 s4' = restore_lvars s2 s4\<rbrakk> \<Longrightarrow> |
|
923 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}ps)-\<succ>v\<rightarrow> s4'" |
860 apply (drule eval.Call, assumption) |
924 apply (drule eval.Call, assumption) |
861 apply (rule HOL.refl) |
925 apply (rule HOL.refl) |
862 apply simp+ |
926 apply simp+ |
863 done |
927 done |
864 |
928 |