91 \item garbage collection not considered, therefore also no finalizers |
91 \item garbage collection not considered, therefore also no finalizers |
92 \item stack overflow and memory overflow during class initialization not |
92 \item stack overflow and memory overflow during class initialization not |
93 modelled |
93 modelled |
94 \item exceptions in initializations not replaced by ExceptionInInitializerError |
94 \item exceptions in initializations not replaced by ExceptionInInitializerError |
95 \end{itemize} |
95 \end{itemize} |
96 *} |
96 \<close> |
97 |
97 |
98 |
98 |
99 type_synonym vvar = "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
99 type_synonym vvar = "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
100 type_synonym vals = "(val, vvar, val list) sum3" |
100 type_synonym vals = "(val, vvar, val list) sum3" |
101 translations |
101 translations |
102 (type) "vvar" <= (type) "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
102 (type) "vvar" <= (type) "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
103 (type) "vals" <= (type) "(val, vvar, val list) sum3" |
103 (type) "vals" <= (type) "(val, vvar, val list) sum3" |
104 |
104 |
105 text {* To avoid redundancy and to reduce the number of rules, there is only |
105 text \<open>To avoid redundancy and to reduce the number of rules, there is only |
106 one evaluation rule for each syntactic term. This is also true for variables |
106 one evaluation rule for each syntactic term. This is also true for variables |
107 (e.g. see the rules below for @{text LVar}, @{text FVar} and @{text AVar}). |
107 (e.g. see the rules below for \<open>LVar\<close>, \<open>FVar\<close> and \<open>AVar\<close>). |
108 So evaluation of a variable must capture both possible further uses: |
108 So evaluation of a variable must capture both possible further uses: |
109 read (rule @{text Acc}) or write (rule @{text Ass}) to the variable. |
109 read (rule \<open>Acc\<close>) or write (rule \<open>Ass\<close>) to the variable. |
110 Therefor a variable evaluates to a special value @{term vvar}, which is |
110 Therefor a variable evaluates to a special value @{term vvar}, which is |
111 a pair, consisting of the current value (for later read access) and an update |
111 a pair, consisting of the current value (for later read access) and an update |
112 function (for later write access). Because |
112 function (for later write access). Because |
113 during assignment to an array variable an exception may occur if the types |
113 during assignment to an array variable an exception may occur if the types |
114 don't match, the update function is very generic: it transforms the |
114 don't match, the update function is very generic: it transforms the |
511 "G\<turnstile>s \<midarrow>c \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In1r c\<succ>\<rightarrow> (\<diamondsuit>, s')" |
511 "G\<turnstile>s \<midarrow>c \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In1r c\<succ>\<rightarrow> (\<diamondsuit>, s')" |
512 | "G\<turnstile>s \<midarrow>e-\<succ>v \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In1l e\<succ>\<rightarrow> (In1 v, s')" |
512 | "G\<turnstile>s \<midarrow>e-\<succ>v \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In1l e\<succ>\<rightarrow> (In1 v, s')" |
513 | "G\<turnstile>s \<midarrow>e=\<succ>vf\<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In2 e\<succ>\<rightarrow> (In2 vf, s')" |
513 | "G\<turnstile>s \<midarrow>e=\<succ>vf\<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In2 e\<succ>\<rightarrow> (In2 vf, s')" |
514 | "G\<turnstile>s \<midarrow>e\<doteq>\<succ>v \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In3 e\<succ>\<rightarrow> (In3 v, s')" |
514 | "G\<turnstile>s \<midarrow>e\<doteq>\<succ>v \<rightarrow> s' \<equiv> G\<turnstile>s \<midarrow>In3 e\<succ>\<rightarrow> (In3 v, s')" |
515 |
515 |
516 --{* propagation of abrupt completion *} |
516 \<comment>\<open>propagation of abrupt completion\<close> |
517 |
517 |
518 --{* cf. 14.1, 15.5 *} |
518 \<comment>\<open>cf. 14.1, 15.5\<close> |
519 | Abrupt: |
519 | Abrupt: |
520 "G\<turnstile>(Some xc,s) \<midarrow>t\<succ>\<rightarrow> (undefined3 t, (Some xc, s))" |
520 "G\<turnstile>(Some xc,s) \<midarrow>t\<succ>\<rightarrow> (undefined3 t, (Some xc, s))" |
521 |
521 |
522 |
522 |
523 --{* execution of statements *} |
523 \<comment>\<open>execution of statements\<close> |
524 |
524 |
525 --{* cf. 14.5 *} |
525 \<comment>\<open>cf. 14.5\<close> |
526 | Skip: "G\<turnstile>Norm s \<midarrow>Skip\<rightarrow> Norm s" |
526 | Skip: "G\<turnstile>Norm s \<midarrow>Skip\<rightarrow> Norm s" |
527 |
527 |
528 --{* cf. 14.7 *} |
528 \<comment>\<open>cf. 14.7\<close> |
529 | Expr: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
529 | Expr: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
530 G\<turnstile>Norm s0 \<midarrow>Expr e\<rightarrow> s1" |
530 G\<turnstile>Norm s0 \<midarrow>Expr e\<rightarrow> s1" |
531 |
531 |
532 | Lab: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c \<rightarrow> s1\<rbrakk> \<Longrightarrow> |
532 | Lab: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c \<rightarrow> s1\<rbrakk> \<Longrightarrow> |
533 G\<turnstile>Norm s0 \<midarrow>l\<bullet> c\<rightarrow> abupd (absorb l) s1" |
533 G\<turnstile>Norm s0 \<midarrow>l\<bullet> c\<rightarrow> abupd (absorb l) s1" |
534 --{* cf. 14.2 *} |
534 \<comment>\<open>cf. 14.2\<close> |
535 | Comp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1 \<rightarrow> s1; |
535 | Comp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1 \<rightarrow> s1; |
536 G\<turnstile> s1 \<midarrow>c2 \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
536 G\<turnstile> s1 \<midarrow>c2 \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
537 G\<turnstile>Norm s0 \<midarrow>c1;; c2\<rightarrow> s2" |
537 G\<turnstile>Norm s0 \<midarrow>c1;; c2\<rightarrow> s2" |
538 |
538 |
539 --{* cf. 14.8.2 *} |
539 \<comment>\<open>cf. 14.8.2\<close> |
540 | If: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
540 | If: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
541 G\<turnstile> s1\<midarrow>(if the_Bool b then c1 else c2)\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
541 G\<turnstile> s1\<midarrow>(if the_Bool b then c1 else c2)\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
542 G\<turnstile>Norm s0 \<midarrow>If(e) c1 Else c2 \<rightarrow> s2" |
542 G\<turnstile>Norm s0 \<midarrow>If(e) c1 Else c2 \<rightarrow> s2" |
543 |
543 |
544 --{* cf. 14.10, 14.10.1 *} |
544 \<comment>\<open>cf. 14.10, 14.10.1\<close> |
545 |
545 |
546 --{* A continue jump from the while body @{term c} is handled by |
546 \<comment>\<open>A continue jump from the while body @{term c} is handled by |
547 this rule. If a continue jump with the proper label was invoked inside |
547 this rule. If a continue jump with the proper label was invoked inside |
548 @{term c} this label (Cont l) is deleted out of the abrupt component of |
548 @{term c} this label (Cont l) is deleted out of the abrupt component of |
549 the state before the iterative evaluation of the while statement. |
549 the state before the iterative evaluation of the while statement. |
550 A break jump is handled by the Lab Statement @{text "Lab l (while\<dots>)"}. |
550 A break jump is handled by the Lab Statement \<open>Lab l (while\<dots>)\<close>. |
551 *} |
551 \<close> |
552 | Loop: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
552 | Loop: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
553 if the_Bool b |
553 if the_Bool b |
554 then (G\<turnstile>s1 \<midarrow>c\<rightarrow> s2 \<and> |
554 then (G\<turnstile>s1 \<midarrow>c\<rightarrow> s2 \<and> |
555 G\<turnstile>(abupd (absorb (Cont l)) s2) \<midarrow>l\<bullet> While(e) c\<rightarrow> s3) |
555 G\<turnstile>(abupd (absorb (Cont l)) s2) \<midarrow>l\<bullet> While(e) c\<rightarrow> s3) |
556 else s3 = s1\<rbrakk> \<Longrightarrow> |
556 else s3 = s1\<rbrakk> \<Longrightarrow> |
557 G\<turnstile>Norm s0 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3" |
557 G\<turnstile>Norm s0 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3" |
558 |
558 |
559 | Jmp: "G\<turnstile>Norm s \<midarrow>Jmp j\<rightarrow> (Some (Jump j), s)" |
559 | Jmp: "G\<turnstile>Norm s \<midarrow>Jmp j\<rightarrow> (Some (Jump j), s)" |
560 |
560 |
561 --{* cf. 14.16 *} |
561 \<comment>\<open>cf. 14.16\<close> |
562 | Throw: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
562 | Throw: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
563 G\<turnstile>Norm s0 \<midarrow>Throw e\<rightarrow> abupd (throw a') s1" |
563 G\<turnstile>Norm s0 \<midarrow>Throw e\<rightarrow> abupd (throw a') s1" |
564 |
564 |
565 --{* cf. 14.18.1 *} |
565 \<comment>\<open>cf. 14.18.1\<close> |
566 | Try: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> s1; G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2; |
566 | Try: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> s1; G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2; |
567 if G,s2\<turnstile>catch C then G\<turnstile>new_xcpt_var vn s2 \<midarrow>c2\<rightarrow> s3 else s3 = s2\<rbrakk> \<Longrightarrow> |
567 if G,s2\<turnstile>catch C then G\<turnstile>new_xcpt_var vn s2 \<midarrow>c2\<rightarrow> s3 else s3 = s2\<rbrakk> \<Longrightarrow> |
568 G\<turnstile>Norm s0 \<midarrow>Try c1 Catch(C vn) c2\<rightarrow> s3" |
568 G\<turnstile>Norm s0 \<midarrow>Try c1 Catch(C vn) c2\<rightarrow> s3" |
569 |
569 |
570 --{* cf. 14.18.2 *} |
570 \<comment>\<open>cf. 14.18.2\<close> |
571 | Fin: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> (x1,s1); |
571 | Fin: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> (x1,s1); |
572 G\<turnstile>Norm s1 \<midarrow>c2\<rightarrow> s2; |
572 G\<turnstile>Norm s1 \<midarrow>c2\<rightarrow> s2; |
573 s3=(if (\<exists> err. x1=Some (Error err)) |
573 s3=(if (\<exists> err. x1=Some (Error err)) |
574 then (x1,s1) |
574 then (x1,s1) |
575 else abupd (abrupt_if (x1\<noteq>None) x1) s2) \<rbrakk> |
575 else abupd (abrupt_if (x1\<noteq>None) x1) s2) \<rbrakk> |
576 \<Longrightarrow> |
576 \<Longrightarrow> |
577 G\<turnstile>Norm s0 \<midarrow>c1 Finally c2\<rightarrow> s3" |
577 G\<turnstile>Norm s0 \<midarrow>c1 Finally c2\<rightarrow> s3" |
578 --{* cf. 12.4.2, 8.5 *} |
578 \<comment>\<open>cf. 12.4.2, 8.5\<close> |
579 | Init: "\<lbrakk>the (class G C) = c; |
579 | Init: "\<lbrakk>the (class G C) = c; |
580 if inited C (globs s0) then s3 = Norm s0 |
580 if inited C (globs s0) then s3 = Norm s0 |
581 else (G\<turnstile>Norm (init_class_obj G C s0) |
581 else (G\<turnstile>Norm (init_class_obj G C s0) |
582 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
582 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
583 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
583 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
584 \<Longrightarrow> |
584 \<Longrightarrow> |
585 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
585 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
586 --{* This class initialisation rule is a little bit inaccurate. Look at the |
586 \<comment>\<open>This class initialisation rule is a little bit inaccurate. Look at the |
587 exact sequence: |
587 exact sequence: |
588 (1) The current class object (the static fields) are initialised |
588 (1) The current class object (the static fields) are initialised |
589 (@{text init_class_obj}), |
589 (\<open>init_class_obj\<close>), |
590 (2) the superclasses are initialised, |
590 (2) the superclasses are initialised, |
591 (3) the static initialiser of the current class is invoked. |
591 (3) the static initialiser of the current class is invoked. |
592 More precisely we should expect another ordering, namely 2 1 3. |
592 More precisely we should expect another ordering, namely 2 1 3. |
593 But we can't just naively toggle 1 and 2. By calling |
593 But we can't just naively toggle 1 and 2. By calling |
594 @{text init_class_obj} |
594 \<open>init_class_obj\<close> |
595 before initialising the superclasses, we also implicitly record that |
595 before initialising the superclasses, we also implicitly record that |
596 we have started to initialise the current class (by setting an |
596 we have started to initialise the current class (by setting an |
597 value for the class object). This becomes |
597 value for the class object). This becomes |
598 crucial for the completeness proof of the axiomatic semantics |
598 crucial for the completeness proof of the axiomatic semantics |
599 @{text "AxCompl.thy"}. Static initialisation requires an induction on |
599 \<open>AxCompl.thy\<close>. Static initialisation requires an induction on |
600 the number of classes not yet initialised (or to be more precise, |
600 the number of classes not yet initialised (or to be more precise, |
601 classes were the initialisation has not yet begun). |
601 classes were the initialisation has not yet begun). |
602 So we could first assign a dummy value to the class before |
602 So we could first assign a dummy value to the class before |
603 superclass initialisation and afterwards set the correct values. |
603 superclass initialisation and afterwards set the correct values. |
604 But as long as we don't take memory overflow into account |
604 But as long as we don't take memory overflow into account |
605 when allocating class objects, we can leave things as they are for |
605 when allocating class objects, we can leave things as they are for |
606 convenience. |
606 convenience. |
607 *} |
607 \<close> |
608 --{* evaluation of expressions *} |
608 \<comment>\<open>evaluation of expressions\<close> |
609 |
609 |
610 --{* cf. 15.8.1, 12.4.1 *} |
610 \<comment>\<open>cf. 15.8.1, 12.4.1\<close> |
611 | NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
611 | NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
612 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> |
613 G\<turnstile>Norm s0 \<midarrow>NewC C-\<succ>Addr a\<rightarrow> s2" |
613 G\<turnstile>Norm s0 \<midarrow>NewC C-\<succ>Addr a\<rightarrow> s2" |
614 |
614 |
615 --{* cf. 15.9.1, 12.4.1 *} |
615 \<comment>\<open>cf. 15.9.1, 12.4.1\<close> |
616 | NewA: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>init_comp_ty T\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>i'\<rightarrow> s2; |
616 | NewA: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>init_comp_ty T\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>i'\<rightarrow> s2; |
617 G\<turnstile>abupd (check_neg i') s2 \<midarrow>halloc (Arr T (the_Intg i'))\<succ>a\<rightarrow> s3\<rbrakk> \<Longrightarrow> |
617 G\<turnstile>abupd (check_neg i') s2 \<midarrow>halloc (Arr T (the_Intg i'))\<succ>a\<rightarrow> s3\<rbrakk> \<Longrightarrow> |
618 G\<turnstile>Norm s0 \<midarrow>New T[e]-\<succ>Addr a\<rightarrow> s3" |
618 G\<turnstile>Norm s0 \<midarrow>New T[e]-\<succ>Addr a\<rightarrow> s3" |
619 |
619 |
620 --{* cf. 15.15 *} |
620 \<comment>\<open>cf. 15.15\<close> |
621 | Cast: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
621 | Cast: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
622 s2 = abupd (raise_if (\<not>G,store s1\<turnstile>v fits T) ClassCast) s1\<rbrakk> \<Longrightarrow> |
622 s2 = abupd (raise_if (\<not>G,store s1\<turnstile>v fits T) ClassCast) s1\<rbrakk> \<Longrightarrow> |
623 G\<turnstile>Norm s0 \<midarrow>Cast T e-\<succ>v\<rightarrow> s2" |
623 G\<turnstile>Norm s0 \<midarrow>Cast T e-\<succ>v\<rightarrow> s2" |
624 |
624 |
625 --{* cf. 15.19.2 *} |
625 \<comment>\<open>cf. 15.19.2\<close> |
626 | Inst: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
626 | Inst: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
627 b = (v\<noteq>Null \<and> G,store s1\<turnstile>v fits RefT T)\<rbrakk> \<Longrightarrow> |
627 b = (v\<noteq>Null \<and> G,store s1\<turnstile>v fits RefT T)\<rbrakk> \<Longrightarrow> |
628 G\<turnstile>Norm s0 \<midarrow>e InstOf T-\<succ>Bool b\<rightarrow> s1" |
628 G\<turnstile>Norm s0 \<midarrow>e InstOf T-\<succ>Bool b\<rightarrow> s1" |
629 |
629 |
630 --{* cf. 15.7.1 *} |
630 \<comment>\<open>cf. 15.7.1\<close> |
631 | Lit: "G\<turnstile>Norm s \<midarrow>Lit v-\<succ>v\<rightarrow> Norm s" |
631 | Lit: "G\<turnstile>Norm s \<midarrow>Lit v-\<succ>v\<rightarrow> Norm s" |
632 |
632 |
633 | UnOp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> |
633 | UnOp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> |
634 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>UnOp unop e-\<succ>(eval_unop unop v)\<rightarrow> s1" |
634 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>UnOp unop e-\<succ>(eval_unop unop v)\<rightarrow> s1" |
635 |
635 |
637 G\<turnstile>s1 \<midarrow>(if need_second_arg binop v1 then (In1l e2) else (In1r Skip)) |
637 G\<turnstile>s1 \<midarrow>(if need_second_arg binop v1 then (In1l e2) else (In1r Skip)) |
638 \<succ>\<rightarrow> (In1 v2, s2) |
638 \<succ>\<rightarrow> (In1 v2, s2) |
639 \<rbrakk> |
639 \<rbrakk> |
640 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>BinOp binop e1 e2-\<succ>(eval_binop binop v1 v2)\<rightarrow> s2" |
640 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>BinOp binop e1 e2-\<succ>(eval_binop binop v1 v2)\<rightarrow> s2" |
641 |
641 |
642 --{* cf. 15.10.2 *} |
642 \<comment>\<open>cf. 15.10.2\<close> |
643 | Super: "G\<turnstile>Norm s \<midarrow>Super-\<succ>val_this s\<rightarrow> Norm s" |
643 | Super: "G\<turnstile>Norm s \<midarrow>Super-\<succ>val_this s\<rightarrow> Norm s" |
644 |
644 |
645 --{* cf. 15.2 *} |
645 \<comment>\<open>cf. 15.2\<close> |
646 | Acc: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(v,f)\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
646 | Acc: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(v,f)\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
647 G\<turnstile>Norm s0 \<midarrow>Acc va-\<succ>v\<rightarrow> s1" |
647 G\<turnstile>Norm s0 \<midarrow>Acc va-\<succ>v\<rightarrow> s1" |
648 |
648 |
649 --{* cf. 15.25.1 *} |
649 \<comment>\<open>cf. 15.25.1\<close> |
650 | Ass: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(w,f)\<rightarrow> s1; |
650 | Ass: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(w,f)\<rightarrow> s1; |
651 G\<turnstile> s1 \<midarrow>e-\<succ>v \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
651 G\<turnstile> s1 \<midarrow>e-\<succ>v \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
652 G\<turnstile>Norm s0 \<midarrow>va:=e-\<succ>v\<rightarrow> assign f v s2" |
652 G\<turnstile>Norm s0 \<midarrow>va:=e-\<succ>v\<rightarrow> assign f v s2" |
653 |
653 |
654 --{* cf. 15.24 *} |
654 \<comment>\<open>cf. 15.24\<close> |
655 | Cond: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e0-\<succ>b\<rightarrow> s1; |
655 | Cond: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e0-\<succ>b\<rightarrow> s1; |
656 G\<turnstile> s1 \<midarrow>(if the_Bool b then e1 else e2)-\<succ>v\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
656 G\<turnstile> s1 \<midarrow>(if the_Bool b then e1 else e2)-\<succ>v\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
657 G\<turnstile>Norm s0 \<midarrow>e0 ? e1 : e2-\<succ>v\<rightarrow> s2" |
657 G\<turnstile>Norm s0 \<midarrow>e0 ? e1 : e2-\<succ>v\<rightarrow> s2" |
658 |
658 |
659 |
659 |
660 -- {* The interplay of @{term Call}, @{term Methd} and @{term Body}: |
660 \<comment> \<open>The interplay of @{term Call}, @{term Methd} and @{term Body}: |
661 Method invocation is split up into these three rules: |
661 Method invocation is split up into these three rules: |
662 \begin{itemize} |
662 \begin{itemize} |
663 \item [@{term Call}] Calculates the target address and evaluates the |
663 \item [@{term Call}] Calculates the target address and evaluates the |
664 arguments of the method, and then performs dynamic |
664 arguments of the method, and then performs dynamic |
665 or static lookup of the method, corresponding to the |
665 or static lookup of the method, corresponding to the |
672 \item [@{term Body}] An extra syntactic entity for the unfolded method |
672 \item [@{term Body}] An extra syntactic entity for the unfolded method |
673 body was introduced to properly trigger class |
673 body was introduced to properly trigger class |
674 initialisation. Without class initialisation we |
674 initialisation. Without class initialisation we |
675 could just evaluate the body statement. |
675 could just evaluate the body statement. |
676 \end{itemize} |
676 \end{itemize} |
677 *} |
677 \<close> |
678 --{* cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5 *} |
678 \<comment>\<open>cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5\<close> |
679 | Call: |
679 | Call: |
680 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
680 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
681 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
681 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
682 s3=init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2; |
682 s3=init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2; |
683 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
683 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
684 G\<turnstile>s3' \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s4\<rbrakk> |
684 G\<turnstile>s3' \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s4\<rbrakk> |
685 \<Longrightarrow> |
685 \<Longrightarrow> |
686 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s4)" |
686 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s4)" |
687 --{* The accessibility check is after @{term init_lvars}, to keep it simple. |
687 \<comment>\<open>The accessibility check is after @{term init_lvars}, to keep it simple. |
688 @{term init_lvars} already tests for the absence of a null-pointer |
688 @{term init_lvars} already tests for the absence of a null-pointer |
689 reference in case of an instance method invocation. |
689 reference in case of an instance method invocation. |
690 *} |
690 \<close> |
691 |
691 |
692 | Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
692 | Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
693 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
693 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
694 |
694 |
695 | Body: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init D\<rightarrow> s1; G\<turnstile>s1 \<midarrow>c\<rightarrow> s2; |
695 | Body: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init D\<rightarrow> s1; G\<turnstile>s1 \<midarrow>c\<rightarrow> s2; |
697 abrupt s2 = Some (Jump (Cont l))) |
697 abrupt s2 = Some (Jump (Cont l))) |
698 then abupd (\<lambda> x. Some (Error CrossMethodJump)) s2 |
698 then abupd (\<lambda> x. Some (Error CrossMethodJump)) s2 |
699 else s2)\<rbrakk> \<Longrightarrow> |
699 else s2)\<rbrakk> \<Longrightarrow> |
700 G\<turnstile>Norm s0 \<midarrow>Body D c-\<succ>the (locals (store s2) Result) |
700 G\<turnstile>Norm s0 \<midarrow>Body D c-\<succ>the (locals (store s2) Result) |
701 \<rightarrow>abupd (absorb Ret) s3" |
701 \<rightarrow>abupd (absorb Ret) s3" |
702 --{* cf. 14.15, 12.4.1 *} |
702 \<comment>\<open>cf. 14.15, 12.4.1\<close> |
703 --{* We filter out a break/continue in @{term s2}, so that we can proof |
703 \<comment>\<open>We filter out a break/continue in @{term s2}, so that we can proof |
704 definite assignment |
704 definite assignment |
705 correct, without the need of conformance of the state. By this the |
705 correct, without the need of conformance of the state. By this the |
706 different parts of the typesafety proof can be disentangled a little. *} |
706 different parts of the typesafety proof can be disentangled a little.\<close> |
707 |
707 |
708 --{* evaluation of variables *} |
708 \<comment>\<open>evaluation of variables\<close> |
709 |
709 |
710 --{* cf. 15.13.1, 15.7.2 *} |
710 \<comment>\<open>cf. 15.13.1, 15.7.2\<close> |
711 | LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
711 | LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
712 |
712 |
713 --{* cf. 15.10.1, 12.4.1 *} |
713 \<comment>\<open>cf. 15.10.1, 12.4.1\<close> |
714 | FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
714 | FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
715 (v,s2') = fvar statDeclC stat fn a s2; |
715 (v,s2') = fvar statDeclC stat fn a s2; |
716 s3 = check_field_access G accC statDeclC fn stat a s2' \<rbrakk> \<Longrightarrow> |
716 s3 = check_field_access G accC statDeclC fn stat a s2' \<rbrakk> \<Longrightarrow> |
717 G\<turnstile>Norm s0 \<midarrow>{accC,statDeclC,stat}e..fn=\<succ>v\<rightarrow> s3" |
717 G\<turnstile>Norm s0 \<midarrow>{accC,statDeclC,stat}e..fn=\<succ>v\<rightarrow> s3" |
718 --{* The accessibility check is after @{term fvar}, to keep it simple. |
718 \<comment>\<open>The accessibility check is after @{term fvar}, to keep it simple. |
719 @{term fvar} already tests for the absence of a null-pointer reference |
719 @{term fvar} already tests for the absence of a null-pointer reference |
720 in case of an instance field |
720 in case of an instance field |
721 *} |
721 \<close> |
722 |
722 |
723 --{* cf. 15.12.1, 15.25.1 *} |
723 \<comment>\<open>cf. 15.12.1, 15.25.1\<close> |
724 | AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
724 | AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
725 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
725 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
726 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
726 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
727 |
727 |
728 |
728 |
729 --{* evaluation of expression lists *} |
729 \<comment>\<open>evaluation of expression lists\<close> |
730 |
730 |
731 --{* cf. 15.11.4.2 *} |
731 \<comment>\<open>cf. 15.11.4.2\<close> |
732 | Nil: |
732 | Nil: |
733 "G\<turnstile>Norm s0 \<midarrow>[]\<doteq>\<succ>[]\<rightarrow> Norm s0" |
733 "G\<turnstile>Norm s0 \<midarrow>[]\<doteq>\<succ>[]\<rightarrow> Norm s0" |
734 |
734 |
735 --{* cf. 15.6.4 *} |
735 \<comment>\<open>cf. 15.6.4\<close> |
736 | Cons: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e -\<succ> v \<rightarrow> s1; |
736 | Cons: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e -\<succ> v \<rightarrow> s1; |
737 G\<turnstile> s1 \<midarrow>es\<doteq>\<succ>vs\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
737 G\<turnstile> s1 \<midarrow>es\<doteq>\<succ>vs\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
738 G\<turnstile>Norm s0 \<midarrow>e#es\<doteq>\<succ>v#vs\<rightarrow> s2" |
738 G\<turnstile>Norm s0 \<midarrow>e#es\<doteq>\<succ>v#vs\<rightarrow> s2" |
739 |
739 |
740 (* Rearrangement of premisses: |
740 (* Rearrangement of premisses: |
742 17(Lit),18(UnOp),19(BinOp),20(Super),21(Acc),3(Expr),5(Comp),25(Methd),26(Body),23(Cond),6(If), |
742 17(Lit),18(UnOp),19(BinOp),20(Super),21(Acc),3(Expr),5(Comp),25(Methd),26(Body),23(Cond),6(If), |
743 7(Loop),11(Fin),9(Throw),13(NewC),14(NewA),12(Init),22(Ass),10(Try),28(FVar), |
743 7(Loop),11(Fin),9(Throw),13(NewC),14(NewA),12(Init),22(Ass),10(Try),28(FVar), |
744 29(AVar),24(Call)] |
744 29(AVar),24(Call)] |
745 *) |
745 *) |
746 |
746 |
747 ML {* |
747 ML \<open> |
748 ML_Thms.bind_thm ("eval_induct", rearrange_prems |
748 ML_Thms.bind_thm ("eval_induct", rearrange_prems |
749 [0,1,2,8,4,30,31,27,15,16, |
749 [0,1,2,8,4,30,31,27,15,16, |
750 17,18,19,20,21,3,5,25,26,23,6, |
750 17,18,19,20,21,3,5,25,26,23,6, |
751 7,11,9,13,14,12,22,10,28, |
751 7,11,9,13,14,12,22,10,28, |
752 29,24] @{thm eval.induct}) |
752 29,24] @{thm eval.induct}) |
753 *} |
753 \<close> |
754 |
754 |
755 |
755 |
756 declare split_if [split del] split_if_asm [split del] |
756 declare split_if [split del] split_if_asm [split del] |
757 option.split [split del] option.split_asm [split del] |
757 option.split [split del] option.split_asm [split del] |
758 inductive_cases halloc_elim_cases: |
758 inductive_cases halloc_elim_cases: |
854 by (auto, frule eval_Inj_elim, auto) |
854 by (auto, frule eval_Inj_elim, auto) |
855 |
855 |
856 lemma eval_stmt_eq: "G\<turnstile>s \<midarrow>In1r t\<succ>\<rightarrow> (w, s') = (w=\<diamondsuit> \<and> G\<turnstile>s \<midarrow>t \<rightarrow> s')" |
856 lemma eval_stmt_eq: "G\<turnstile>s \<midarrow>In1r t\<succ>\<rightarrow> (w, s') = (w=\<diamondsuit> \<and> G\<turnstile>s \<midarrow>t \<rightarrow> s')" |
857 by (auto, frule eval_Inj_elim, auto, frule eval_Inj_elim, auto) |
857 by (auto, frule eval_Inj_elim, auto, frule eval_Inj_elim, auto) |
858 |
858 |
859 simproc_setup eval_expr ("G\<turnstile>s \<midarrow>In1l t\<succ>\<rightarrow> (w, s')") = {* |
859 simproc_setup eval_expr ("G\<turnstile>s \<midarrow>In1l t\<succ>\<rightarrow> (w, s')") = \<open> |
860 fn _ => fn _ => fn ct => |
860 fn _ => fn _ => fn ct => |
861 (case Thm.term_of ct of |
861 (case Thm.term_of ct of |
862 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
862 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
863 | _ => SOME (mk_meta_eq @{thm eval_expr_eq})) *} |
863 | _ => SOME (mk_meta_eq @{thm eval_expr_eq}))\<close> |
864 |
864 |
865 simproc_setup eval_var ("G\<turnstile>s \<midarrow>In2 t\<succ>\<rightarrow> (w, s')") = {* |
865 simproc_setup eval_var ("G\<turnstile>s \<midarrow>In2 t\<succ>\<rightarrow> (w, s')") = \<open> |
866 fn _ => fn _ => fn ct => |
866 fn _ => fn _ => fn ct => |
867 (case Thm.term_of ct of |
867 (case Thm.term_of ct of |
868 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
868 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
869 | _ => SOME (mk_meta_eq @{thm eval_var_eq})) *} |
869 | _ => SOME (mk_meta_eq @{thm eval_var_eq}))\<close> |
870 |
870 |
871 simproc_setup eval_exprs ("G\<turnstile>s \<midarrow>In3 t\<succ>\<rightarrow> (w, s')") = {* |
871 simproc_setup eval_exprs ("G\<turnstile>s \<midarrow>In3 t\<succ>\<rightarrow> (w, s')") = \<open> |
872 fn _ => fn _ => fn ct => |
872 fn _ => fn _ => fn ct => |
873 (case Thm.term_of ct of |
873 (case Thm.term_of ct of |
874 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
874 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
875 | _ => SOME (mk_meta_eq @{thm eval_exprs_eq})) *} |
875 | _ => SOME (mk_meta_eq @{thm eval_exprs_eq}))\<close> |
876 |
876 |
877 simproc_setup eval_stmt ("G\<turnstile>s \<midarrow>In1r t\<succ>\<rightarrow> (w, s')") = {* |
877 simproc_setup eval_stmt ("G\<turnstile>s \<midarrow>In1r t\<succ>\<rightarrow> (w, s')") = \<open> |
878 fn _ => fn _ => fn ct => |
878 fn _ => fn _ => fn ct => |
879 (case Thm.term_of ct of |
879 (case Thm.term_of ct of |
880 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
880 (_ $ _ $ _ $ _ $ (Const _ $ _) $ _) => NONE |
881 | _ => SOME (mk_meta_eq @{thm eval_stmt_eq})) *} |
881 | _ => SOME (mk_meta_eq @{thm eval_stmt_eq}))\<close> |
882 |
882 |
883 ML {* |
883 ML \<open> |
884 ML_Thms.bind_thms ("AbruptIs", sum3_instantiate @{context} @{thm eval.Abrupt}) |
884 ML_Thms.bind_thms ("AbruptIs", sum3_instantiate @{context} @{thm eval.Abrupt}) |
885 *} |
885 \<close> |
886 |
886 |
887 declare halloc.Abrupt [intro!] eval.Abrupt [intro!] AbruptIs [intro!] |
887 declare halloc.Abrupt [intro!] eval.Abrupt [intro!] AbruptIs [intro!] |
888 |
888 |
889 text{* @{text Callee},@{text InsInitE}, @{text InsInitV}, @{text FinA} are only |
889 text\<open>\<open>Callee\<close>,\<open>InsInitE\<close>, \<open>InsInitV\<close>, \<open>FinA\<close> are only |
890 used in smallstep semantics, not in the bigstep semantics. So their is no |
890 used in smallstep semantics, not in the bigstep semantics. So their is no |
891 valid evaluation of these terms |
891 valid evaluation of these terms |
892 *} |
892 \<close> |
893 |
893 |
894 |
894 |
895 lemma eval_Callee: "G\<turnstile>Norm s\<midarrow>Callee l e-\<succ>v\<rightarrow> s' = False" |
895 lemma eval_Callee: "G\<turnstile>Norm s\<midarrow>Callee l e-\<succ>v\<rightarrow> s' = False" |
896 proof - |
896 proof - |
897 { fix s t v s' |
897 { fix s t v s' |