95 modelled |
95 modelled |
96 \item exceptions in initializations not replaced by ExceptionInInitializerError |
96 \item exceptions in initializations not replaced by ExceptionInInitializerError |
97 \end{itemize} |
97 \end{itemize} |
98 *} |
98 *} |
99 |
99 |
|
100 |
100 types vvar = "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
101 types vvar = "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
101 vals = "(val, vvar, val list) sum3" |
102 vals = "(val, vvar, val list) sum3" |
102 translations |
103 translations |
103 "vvar" <= (type) "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
104 "vvar" <= (type) "val \<times> (val \<Rightarrow> state \<Rightarrow> state)" |
104 "vals" <= (type)"(val, vvar, val list) sum3" |
105 "vals" <= (type)"(val, vvar, val list) sum3" |
|
106 |
|
107 text {* To avoid redundancy and to reduce the number of rules, there is only |
|
108 one evaluation rule for each syntactic term. This is also true for variables |
|
109 (e.g. see the rules below for @{text LVar}, @{text FVar} and @{text AVar}). |
|
110 So evaluation of a variable must capture both possible further uses: |
|
111 read (rule @{text Acc}) or write (rule @{text Ass}) to the variable. |
|
112 Therefor a variable evaluates to a special value @{term vvar}, which is |
|
113 a pair, consisting of the current value (for later read access) and an update |
|
114 function (for later write access). Because |
|
115 during assignment to an array variable an exception may occur if the types |
|
116 don't match, the update function is very generic: it transforms the |
|
117 full state. This generic update function causes some technical trouble during |
|
118 some proofs (e.g. type safety, correctness of definite assignment). There we |
|
119 need to prove some additional invariant on this update function to prove the |
|
120 assignment correct, since the update function could potentially alter the whole |
|
121 state in an arbitrary manner. This invariant must be carried around through |
|
122 the whole induction. |
|
123 So for future approaches it may be better not to take |
|
124 such a generic update function, but only to store the address and the kind |
|
125 of variable (array (+ element type), local variable or field) for later |
|
126 assignment. |
|
127 *} |
105 |
128 |
106 syntax (xsymbols) |
129 syntax (xsymbols) |
107 dummy_res :: "vals" ("\<diamondsuit>") |
130 dummy_res :: "vals" ("\<diamondsuit>") |
108 translations |
131 translations |
109 "\<diamondsuit>" == "In1 Unit" |
132 "\<diamondsuit>" == "In1 Unit" |
|
133 |
|
134 syntax |
|
135 val_inj_vals:: "expr \<Rightarrow> term" ("\<lfloor>_\<rfloor>\<^sub>e" 1000) |
|
136 var_inj_vals:: "var \<Rightarrow> term" ("\<lfloor>_\<rfloor>\<^sub>v" 1000) |
|
137 lst_inj_vals:: "expr list \<Rightarrow> term" ("\<lfloor>_\<rfloor>\<^sub>l" 1000) |
|
138 |
|
139 translations |
|
140 "\<lfloor>e\<rfloor>\<^sub>e" \<rightharpoonup> "In1 e" |
|
141 "\<lfloor>v\<rfloor>\<^sub>v" \<rightharpoonup> "In2 v" |
|
142 "\<lfloor>es\<rfloor>\<^sub>l" \<rightharpoonup> "In3 es" |
110 |
143 |
111 constdefs |
144 constdefs |
112 arbitrary3 :: "('al + 'ar, 'b, 'c) sum3 \<Rightarrow> vals" |
145 arbitrary3 :: "('al + 'ar, 'b, 'c) sum3 \<Rightarrow> vals" |
113 "arbitrary3 \<equiv> sum3_case (In1 \<circ> sum_case (\<lambda>x. arbitrary) (\<lambda>x. Unit)) |
146 "arbitrary3 \<equiv> sum3_case (In1 \<circ> sum_case (\<lambda>x. arbitrary) (\<lambda>x. Unit)) |
114 (\<lambda>x. In2 arbitrary) (\<lambda>x. In3 arbitrary)" |
147 (\<lambda>x. In2 arbitrary) (\<lambda>x. In3 arbitrary)" |
445 (error_if (\<not> G\<turnstile>Methd sig dynM in invC dyn_accessible_from accC) |
472 (error_if (\<not> G\<turnstile>Methd sig dynM in invC dyn_accessible_from accC) |
446 AccessViolation) |
473 AccessViolation) |
447 s" |
474 s" |
448 |
475 |
449 section "evaluation judgments" |
476 section "evaluation judgments" |
450 |
|
451 consts eval_unop :: "unop \<Rightarrow> val \<Rightarrow> val" |
|
452 primrec |
|
453 "eval_unop UPlus v = Intg (the_Intg v)" |
|
454 "eval_unop UMinus v = Intg (- (the_Intg v))" |
|
455 "eval_unop UBitNot v = Intg 42" -- "FIXME: Not yet implemented" |
|
456 "eval_unop UNot v = Bool (\<not> the_Bool v)" |
|
457 |
|
458 consts eval_binop :: "binop \<Rightarrow> val \<Rightarrow> val \<Rightarrow> val" |
|
459 primrec |
|
460 "eval_binop Mul v1 v2 = Intg ((the_Intg v1) * (the_Intg v2))" |
|
461 "eval_binop Div v1 v2 = Intg ((the_Intg v1) div (the_Intg v2))" |
|
462 "eval_binop Mod v1 v2 = Intg ((the_Intg v1) mod (the_Intg v2))" |
|
463 "eval_binop Plus v1 v2 = Intg ((the_Intg v1) + (the_Intg v2))" |
|
464 "eval_binop Minus v1 v2 = Intg ((the_Intg v1) - (the_Intg v2))" |
|
465 |
|
466 -- "Be aware of the explicit coercion of the shift distance to nat" |
|
467 "eval_binop LShift v1 v2 = Intg ((the_Intg v1) * (2^(nat (the_Intg v2))))" |
|
468 "eval_binop RShift v1 v2 = Intg ((the_Intg v1) div (2^(nat (the_Intg v2))))" |
|
469 "eval_binop RShiftU v1 v2 = Intg 42" --"FIXME: Not yet implemented" |
|
470 |
|
471 "eval_binop Less v1 v2 = Bool ((the_Intg v1) < (the_Intg v2))" |
|
472 "eval_binop Le v1 v2 = Bool ((the_Intg v1) \<le> (the_Intg v2))" |
|
473 "eval_binop Greater v1 v2 = Bool ((the_Intg v2) < (the_Intg v1))" |
|
474 "eval_binop Ge v1 v2 = Bool ((the_Intg v2) \<le> (the_Intg v1))" |
|
475 |
|
476 "eval_binop Eq v1 v2 = Bool (v1=v2)" |
|
477 "eval_binop Neq v1 v2 = Bool (v1\<noteq>v2)" |
|
478 "eval_binop BitAnd v1 v2 = Intg 42" -- "FIXME: Not yet implemented" |
|
479 "eval_binop And v1 v2 = Bool ((the_Bool v1) \<and> (the_Bool v2))" |
|
480 "eval_binop BitXor v1 v2 = Intg 42" -- "FIXME: Not yet implemented" |
|
481 "eval_binop Xor v1 v2 = Bool ((the_Bool v1) \<noteq> (the_Bool v2))" |
|
482 "eval_binop BitOr v1 v2 = Intg 42" -- "FIXME: Not yet implemented" |
|
483 "eval_binop Or v1 v2 = Bool ((the_Bool v1) \<or> (the_Bool v2))" |
|
484 "eval_binop CondAnd v1 v2 = Bool ((the_Bool v1) \<and> (the_Bool v2))" |
|
485 "eval_binop CondOr v1 v2 = Bool ((the_Bool v1) \<or> (the_Bool v2))" |
|
486 |
|
487 constdefs need_second_arg :: "binop \<Rightarrow> val \<Rightarrow> bool" |
|
488 "need_second_arg binop v1 \<equiv> \<not> ((binop=CondAnd \<and> \<not> the_Bool v1) \<or> |
|
489 (binop=CondOr \<and> the_Bool v1))" |
|
490 text {* @{term CondAnd} and @{term CondOr} only evalulate the second argument |
|
491 if the value isn't already determined by the first argument*} |
|
492 |
|
493 lemma need_second_arg_CondAnd [simp]: "need_second_arg CondAnd (Bool b) = b" |
|
494 by (simp add: need_second_arg_def) |
|
495 |
|
496 lemma need_second_arg_CondOr [simp]: "need_second_arg CondOr (Bool b) = (\<not> b)" |
|
497 by (simp add: need_second_arg_def) |
|
498 |
|
499 lemma need_second_arg_strict[simp]: |
|
500 "\<lbrakk>binop\<noteq>CondAnd; binop\<noteq>CondOr\<rbrakk> \<Longrightarrow> need_second_arg binop b" |
|
501 by (cases binop) |
|
502 (simp_all add: need_second_arg_def) |
|
503 |
477 |
504 consts |
478 consts |
505 eval :: "prog \<Rightarrow> (state \<times> term \<times> vals \<times> state) set" |
479 eval :: "prog \<Rightarrow> (state \<times> term \<times> vals \<times> state) set" |
506 halloc:: "prog \<Rightarrow> (state \<times> obj_tag \<times> loc \<times> state) set" |
480 halloc:: "prog \<Rightarrow> (state \<times> obj_tag \<times> loc \<times> state) set" |
507 sxalloc:: "prog \<Rightarrow> (state \<times> state) set" |
481 sxalloc:: "prog \<Rightarrow> (state \<times> state) set" |
544 "G\<turnstile>s \<midarrow>halloc oi\<succ>a\<rightarrow> (x,s')" <= "(s,oi,a,x,s') \<in> halloc G" |
518 "G\<turnstile>s \<midarrow>halloc oi\<succ>a\<rightarrow> (x,s')" <= "(s,oi,a,x,s') \<in> halloc G" |
545 "G\<turnstile>s \<midarrow>halloc oi\<succ>a\<rightarrow> s' " == "(s,oi,a, s') \<in> halloc G" |
519 "G\<turnstile>s \<midarrow>halloc oi\<succ>a\<rightarrow> s' " == "(s,oi,a, s') \<in> halloc G" |
546 "G\<turnstile>s \<midarrow>sxalloc\<rightarrow> (x,s')" <= "(s ,x,s') \<in> sxalloc G" |
520 "G\<turnstile>s \<midarrow>sxalloc\<rightarrow> (x,s')" <= "(s ,x,s') \<in> sxalloc G" |
547 "G\<turnstile>s \<midarrow>sxalloc\<rightarrow> s' " == "(s , s') \<in> sxalloc G" |
521 "G\<turnstile>s \<midarrow>sxalloc\<rightarrow> s' " == "(s , s') \<in> sxalloc G" |
548 |
522 |
549 inductive "halloc G" intros (* allocating objects on the heap, cf. 12.5 *) |
523 inductive "halloc G" intros --{* allocating objects on the heap, cf. 12.5 *} |
550 |
524 |
551 Abrupt: |
525 Abrupt: |
552 "G\<turnstile>(Some x,s) \<midarrow>halloc oi\<succ>arbitrary\<rightarrow> (Some x,s)" |
526 "G\<turnstile>(Some x,s) \<midarrow>halloc oi\<succ>arbitrary\<rightarrow> (Some x,s)" |
553 |
527 |
554 New: "\<lbrakk>new_Addr (heap s) = Some a; |
528 New: "\<lbrakk>new_Addr (heap s) = Some a; |
555 (x,oi') = (if atleast_free (heap s) (Suc (Suc 0)) then (None,oi) |
529 (x,oi') = (if atleast_free (heap s) (Suc (Suc 0)) then (None,oi) |
556 else (Some (Xcpt (Loc a)),CInst (SXcpt OutOfMemory)))\<rbrakk> |
530 else (Some (Xcpt (Loc a)),CInst (SXcpt OutOfMemory)))\<rbrakk> |
557 \<Longrightarrow> |
531 \<Longrightarrow> |
558 G\<turnstile>Norm s \<midarrow>halloc oi\<succ>a\<rightarrow> (x,init_obj G oi' (Heap a) s)" |
532 G\<turnstile>Norm s \<midarrow>halloc oi\<succ>a\<rightarrow> (x,init_obj G oi' (Heap a) s)" |
559 |
533 |
560 inductive "sxalloc G" intros (* allocating exception objects for |
534 inductive "sxalloc G" intros --{* allocating exception objects for |
561 standard exceptions (other than OutOfMemory) *) |
535 standard exceptions (other than OutOfMemory) *} |
562 |
536 |
563 Norm: "G\<turnstile> Norm s \<midarrow>sxalloc\<rightarrow> Norm s" |
537 Norm: "G\<turnstile> Norm s \<midarrow>sxalloc\<rightarrow> Norm s" |
|
538 |
|
539 Jmp: "G\<turnstile>(Some (Jump j), s) \<midarrow>sxalloc\<rightarrow> (Some (Jump j), s)" |
|
540 |
|
541 Error: "G\<turnstile>(Some (Error e), s) \<midarrow>sxalloc\<rightarrow> (Some (Error e), s)" |
564 |
542 |
565 XcptL: "G\<turnstile>(Some (Xcpt (Loc a) ),s) \<midarrow>sxalloc\<rightarrow> (Some (Xcpt (Loc a)),s)" |
543 XcptL: "G\<turnstile>(Some (Xcpt (Loc a) ),s) \<midarrow>sxalloc\<rightarrow> (Some (Xcpt (Loc a)),s)" |
566 |
544 |
567 SXcpt: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>halloc (CInst (SXcpt xn))\<succ>a\<rightarrow> (x,s1)\<rbrakk> \<Longrightarrow> |
545 SXcpt: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>halloc (CInst (SXcpt xn))\<succ>a\<rightarrow> (x,s1)\<rbrakk> \<Longrightarrow> |
568 G\<turnstile>(Some (Xcpt (Std xn)),s0) \<midarrow>sxalloc\<rightarrow> (Some (Xcpt (Loc a)),s1)" |
546 G\<turnstile>(Some (Xcpt (Std xn)),s0) \<midarrow>sxalloc\<rightarrow> (Some (Xcpt (Loc a)),s1)" |
|
547 |
569 |
548 |
570 text {* |
549 text {* |
571 \par |
550 \par |
572 *} (* dummy text command to break paragraph for latex; |
551 *} (* dummy text command to break paragraph for latex; |
573 large paragraphs exhaust memory of debian pdflatex *) |
552 large paragraphs exhaust memory of debian pdflatex *) |
574 |
553 |
|
554 |
575 inductive "eval G" intros |
555 inductive "eval G" intros |
576 |
556 |
577 (* propagation of abrupt completion *) |
557 --{* propagation of abrupt completion *} |
578 |
558 |
579 (* cf. 14.1, 15.5 *) |
559 --{* cf. 14.1, 15.5 *} |
580 Abrupt: |
560 Abrupt: |
581 "G\<turnstile>(Some xc,s) \<midarrow>t\<succ>\<rightarrow> (arbitrary3 t,(Some xc,s))" |
561 "G\<turnstile>(Some xc,s) \<midarrow>t\<succ>\<rightarrow> (arbitrary3 t,(Some xc,s))" |
582 |
562 |
583 |
563 |
584 (* execution of statements *) |
564 --{* execution of statements *} |
585 |
565 |
586 (* cf. 14.5 *) |
566 --{* cf. 14.5 *} |
587 Skip: "G\<turnstile>Norm s \<midarrow>Skip\<rightarrow> Norm s" |
567 Skip: "G\<turnstile>Norm s \<midarrow>Skip\<rightarrow> Norm s" |
588 |
568 |
589 (* cf. 14.7 *) |
569 --{* cf. 14.7 *} |
590 Expr: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
570 Expr: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
591 G\<turnstile>Norm s0 \<midarrow>Expr e\<rightarrow> s1" |
571 G\<turnstile>Norm s0 \<midarrow>Expr e\<rightarrow> s1" |
592 |
572 |
593 Lab: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c \<rightarrow> s1\<rbrakk> \<Longrightarrow> |
573 Lab: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c \<rightarrow> s1\<rbrakk> \<Longrightarrow> |
594 G\<turnstile>Norm s0 \<midarrow>l\<bullet> c\<rightarrow> abupd (absorb l) s1" |
574 G\<turnstile>Norm s0 \<midarrow>l\<bullet> c\<rightarrow> abupd (absorb l) s1" |
595 (* cf. 14.2 *) |
575 --{* cf. 14.2 *} |
596 Comp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1 \<rightarrow> s1; |
576 Comp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1 \<rightarrow> s1; |
597 G\<turnstile> s1 \<midarrow>c2 \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
577 G\<turnstile> s1 \<midarrow>c2 \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
598 G\<turnstile>Norm s0 \<midarrow>c1;; c2\<rightarrow> s2" |
578 G\<turnstile>Norm s0 \<midarrow>c1;; c2\<rightarrow> s2" |
599 |
579 |
600 |
580 --{* cf. 14.8.2 *} |
601 (* cf. 14.8.2 *) |
|
602 If: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
581 If: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
603 G\<turnstile> s1\<midarrow>(if the_Bool b then c1 else c2)\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
582 G\<turnstile> s1\<midarrow>(if the_Bool b then c1 else c2)\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
604 G\<turnstile>Norm s0 \<midarrow>If(e) c1 Else c2 \<rightarrow> s2" |
583 G\<turnstile>Norm s0 \<midarrow>If(e) c1 Else c2 \<rightarrow> s2" |
605 |
584 |
606 (* cf. 14.10, 14.10.1 *) |
585 --{* cf. 14.10, 14.10.1 *} |
607 (* G\<turnstile>Norm s0 \<midarrow>If(e) (c;; While(e) c) Else Skip\<rightarrow> s3 *) |
586 |
608 (* A "continue jump" from the while body c is handled by |
587 --{* A continue jump from the while body @{term c} is handled by |
609 this rule. If a continue jump with the proper label was invoked inside c |
588 this rule. If a continue jump with the proper label was invoked inside |
610 this label (Cont l) is deleted out of the abrupt component of the state |
589 @{term c} this label (Cont l) is deleted out of the abrupt component of |
611 before the iterative evaluation of the while statement. |
590 the state before the iterative evaluation of the while statement. |
612 A "break jump" is handled by the Lab Statement (Lab l (while\<dots>). |
591 A break jump is handled by the Lab Statement @{text "Lab l (while\<dots>)"}. |
613 *) |
592 *} |
614 Loop: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
593 Loop: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>b\<rightarrow> s1; |
615 if normal s1 \<and> the_Bool b |
594 if the_Bool b |
616 then (G\<turnstile>s1 \<midarrow>c\<rightarrow> s2 \<and> |
595 then (G\<turnstile>s1 \<midarrow>c\<rightarrow> s2 \<and> |
617 G\<turnstile>(abupd (absorb (Cont l)) s2) \<midarrow>l\<bullet> While(e) c\<rightarrow> s3) |
596 G\<turnstile>(abupd (absorb (Cont l)) s2) \<midarrow>l\<bullet> While(e) c\<rightarrow> s3) |
618 else s3 = s1\<rbrakk> \<Longrightarrow> |
597 else s3 = s1\<rbrakk> \<Longrightarrow> |
619 G\<turnstile>Norm s0 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3" |
598 G\<turnstile>Norm s0 \<midarrow>l\<bullet> While(e) c\<rightarrow> s3" |
620 |
599 |
621 Do: "G\<turnstile>Norm s \<midarrow>Do j\<rightarrow> (Some (Jump j), s)" |
600 Jmp: "G\<turnstile>Norm s \<midarrow>Jmp j\<rightarrow> (Some (Jump j), s)" |
622 |
601 |
623 (* cf. 14.16 *) |
602 --{* cf. 14.16 *} |
624 Throw: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
603 Throw: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
625 G\<turnstile>Norm s0 \<midarrow>Throw e\<rightarrow> abupd (throw a') s1" |
604 G\<turnstile>Norm s0 \<midarrow>Throw e\<rightarrow> abupd (throw a') s1" |
626 |
605 |
627 (* cf. 14.18.1 *) |
606 --{* cf. 14.18.1 *} |
628 Try: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> s1; G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2; |
607 Try: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> s1; G\<turnstile>s1 \<midarrow>sxalloc\<rightarrow> s2; |
629 if G,s2\<turnstile>catch C then G\<turnstile>new_xcpt_var vn s2 \<midarrow>c2\<rightarrow> s3 else s3 = s2\<rbrakk> \<Longrightarrow> |
608 if G,s2\<turnstile>catch C then G\<turnstile>new_xcpt_var vn s2 \<midarrow>c2\<rightarrow> s3 else s3 = s2\<rbrakk> \<Longrightarrow> |
630 G\<turnstile>Norm s0 \<midarrow>Try c1 Catch(C vn) c2\<rightarrow> s3" |
609 G\<turnstile>Norm s0 \<midarrow>Try c1 Catch(C vn) c2\<rightarrow> s3" |
631 |
610 |
632 (* cf. 14.18.2 *) |
611 --{* cf. 14.18.2 *} |
633 Fin: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> (x1,s1); |
612 Fin: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>c1\<rightarrow> (x1,s1); |
634 G\<turnstile>Norm s1 \<midarrow>c2\<rightarrow> s2; |
613 G\<turnstile>Norm s1 \<midarrow>c2\<rightarrow> s2; |
635 s3=(if (\<exists> err. x1=Some (Error err)) |
614 s3=(if (\<exists> err. x1=Some (Error err)) |
636 then (x1,s1) |
615 then (x1,s1) |
637 else abupd (abrupt_if (x1\<noteq>None) x1) s2) \<rbrakk> |
616 else abupd (abrupt_if (x1\<noteq>None) x1) s2) \<rbrakk> |
638 \<Longrightarrow> |
617 \<Longrightarrow> |
639 G\<turnstile>Norm s0 \<midarrow>c1 Finally c2\<rightarrow> s3" |
618 G\<turnstile>Norm s0 \<midarrow>c1 Finally c2\<rightarrow> s3" |
640 (* cf. 12.4.2, 8.5 *) |
619 --{* cf. 12.4.2, 8.5 *} |
641 Init: "\<lbrakk>the (class G C) = c; |
620 Init: "\<lbrakk>the (class G C) = c; |
642 if inited C (globs s0) then s3 = Norm s0 |
621 if inited C (globs s0) then s3 = Norm s0 |
643 else (G\<turnstile>Norm (init_class_obj G C s0) |
622 else (G\<turnstile>Norm (init_class_obj G C s0) |
644 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
623 \<midarrow>(if C = Object then Skip else Init (super c))\<rightarrow> s1 \<and> |
645 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
624 G\<turnstile>set_lvars empty s1 \<midarrow>init c\<rightarrow> s2 \<and> s3 = restore_lvars s1 s2)\<rbrakk> |
646 \<Longrightarrow> |
625 \<Longrightarrow> |
647 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
626 G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s3" |
648 (* This class initialisation rule is a little bit inaccurate. Look at the |
627 --{* This class initialisation rule is a little bit inaccurate. Look at the |
649 exact sequence: |
628 exact sequence: |
650 1. The current class object (the static fields) are initialised |
629 (1) The current class object (the static fields) are initialised |
651 (init_class_obj) |
630 (@{text init_class_obj}), |
652 2. Then the superclasses are initialised |
631 (2) the superclasses are initialised, |
653 3. The static initialiser of the current class is invoked |
632 (3) the static initialiser of the current class is invoked. |
654 More precisely we should expect another ordering, namely 2 1 3. |
633 More precisely we should expect another ordering, namely 2 1 3. |
655 But we can't just naively toggle 1 and 2. By calling init_class_obj |
634 But we can't just naively toggle 1 and 2. By calling |
656 before initialising the superclasses we also implicitly record that |
635 @{text init_class_obj} |
|
636 before initialising the superclasses, we also implicitly record that |
657 we have started to initialise the current class (by setting an |
637 we have started to initialise the current class (by setting an |
658 value for the class object). This becomes |
638 value for the class object). This becomes |
659 crucial for the completeness proof of the axiomatic semantics |
639 crucial for the completeness proof of the axiomatic semantics |
660 (AxCompl.thy). Static initialisation requires an induction on the number |
640 @{text "AxCompl.thy"}. Static initialisation requires an induction on |
661 of classes not yet initialised (or to be more precise, classes where the |
641 the number of classes not yet initialised (or to be more precise, |
662 initialisation has not yet begun). |
642 classes were the initialisation has not yet begun). |
663 So we could first assign a dummy value to the class before |
643 So we could first assign a dummy value to the class before |
664 superclass initialisation and afterwards set the correct values. |
644 superclass initialisation and afterwards set the correct values. |
665 But as long as we don't take memory overflow into account |
645 But as long as we don't take memory overflow into account |
666 when allocating class objects, and don't model definite assignment in |
646 when allocating class objects, we can leave things as they are for |
667 the static initialisers, we can leave things as they are for convenience. |
647 convenience. |
668 *) |
648 *} |
669 (* evaluation of expressions *) |
649 --{* evaluation of expressions *} |
670 |
650 |
671 (* cf. 15.8.1, 12.4.1 *) |
651 --{* cf. 15.8.1, 12.4.1 *} |
672 NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
652 NewC: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init C\<rightarrow> s1; |
673 G\<turnstile> s1 \<midarrow>halloc (CInst C)\<succ>a\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
653 G\<turnstile> s1 \<midarrow>halloc (CInst C)\<succ>a\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
674 G\<turnstile>Norm s0 \<midarrow>NewC C-\<succ>Addr a\<rightarrow> s2" |
654 G\<turnstile>Norm s0 \<midarrow>NewC C-\<succ>Addr a\<rightarrow> s2" |
675 |
655 |
676 (* cf. 15.9.1, 12.4.1 *) |
656 --{* cf. 15.9.1, 12.4.1 *} |
677 NewA: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>init_comp_ty T\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>i'\<rightarrow> s2; |
657 NewA: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>init_comp_ty T\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>i'\<rightarrow> s2; |
678 G\<turnstile>abupd (check_neg i') s2 \<midarrow>halloc (Arr T (the_Intg i'))\<succ>a\<rightarrow> s3\<rbrakk> \<Longrightarrow> |
658 G\<turnstile>abupd (check_neg i') s2 \<midarrow>halloc (Arr T (the_Intg i'))\<succ>a\<rightarrow> s3\<rbrakk> \<Longrightarrow> |
679 G\<turnstile>Norm s0 \<midarrow>New T[e]-\<succ>Addr a\<rightarrow> s3" |
659 G\<turnstile>Norm s0 \<midarrow>New T[e]-\<succ>Addr a\<rightarrow> s3" |
680 |
660 |
681 (* cf. 15.15 *) |
661 --{* cf. 15.15 *} |
682 Cast: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
662 Cast: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
683 s2 = abupd (raise_if (\<not>G,store s1\<turnstile>v fits T) ClassCast) s1\<rbrakk> \<Longrightarrow> |
663 s2 = abupd (raise_if (\<not>G,store s1\<turnstile>v fits T) ClassCast) s1\<rbrakk> \<Longrightarrow> |
684 G\<turnstile>Norm s0 \<midarrow>Cast T e-\<succ>v\<rightarrow> s2" |
664 G\<turnstile>Norm s0 \<midarrow>Cast T e-\<succ>v\<rightarrow> s2" |
685 |
665 |
686 (* cf. 15.19.2 *) |
666 --{* cf. 15.19.2 *} |
687 Inst: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
667 Inst: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1; |
688 b = (v\<noteq>Null \<and> G,store s1\<turnstile>v fits RefT T)\<rbrakk> \<Longrightarrow> |
668 b = (v\<noteq>Null \<and> G,store s1\<turnstile>v fits RefT T)\<rbrakk> \<Longrightarrow> |
689 G\<turnstile>Norm s0 \<midarrow>e InstOf T-\<succ>Bool b\<rightarrow> s1" |
669 G\<turnstile>Norm s0 \<midarrow>e InstOf T-\<succ>Bool b\<rightarrow> s1" |
690 |
670 |
691 (* cf. 15.7.1 *) |
671 --{* cf. 15.7.1 *} |
692 Lit: "G\<turnstile>Norm s \<midarrow>Lit v-\<succ>v\<rightarrow> Norm s" |
672 Lit: "G\<turnstile>Norm s \<midarrow>Lit v-\<succ>v\<rightarrow> Norm s" |
693 |
673 |
694 UnOp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> |
674 UnOp: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>v\<rightarrow> s1\<rbrakk> |
695 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>UnOp unop e-\<succ>(eval_unop unop v)\<rightarrow> s1" |
675 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>UnOp unop e-\<succ>(eval_unop unop v)\<rightarrow> s1" |
696 |
676 |
698 G\<turnstile>s1 \<midarrow>(if need_second_arg binop v1 then (In1l e2) else (In1r Skip)) |
678 G\<turnstile>s1 \<midarrow>(if need_second_arg binop v1 then (In1l e2) else (In1r Skip)) |
699 \<succ>\<rightarrow> (In1 v2,s2) |
679 \<succ>\<rightarrow> (In1 v2,s2) |
700 \<rbrakk> |
680 \<rbrakk> |
701 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>BinOp binop e1 e2-\<succ>(eval_binop binop v1 v2)\<rightarrow> s2" |
681 \<Longrightarrow> G\<turnstile>Norm s0 \<midarrow>BinOp binop e1 e2-\<succ>(eval_binop binop v1 v2)\<rightarrow> s2" |
702 |
682 |
703 (* cf. 15.10.2 *) |
683 --{* cf. 15.10.2 *} |
704 Super: "G\<turnstile>Norm s \<midarrow>Super-\<succ>val_this s\<rightarrow> Norm s" |
684 Super: "G\<turnstile>Norm s \<midarrow>Super-\<succ>val_this s\<rightarrow> Norm s" |
705 |
685 |
706 (* cf. 15.2 *) |
686 --{* cf. 15.2 *} |
707 Acc: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(v,f)\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
687 Acc: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(v,f)\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
708 G\<turnstile>Norm s0 \<midarrow>Acc va-\<succ>v\<rightarrow> s1" |
688 G\<turnstile>Norm s0 \<midarrow>Acc va-\<succ>v\<rightarrow> s1" |
709 |
689 |
710 (* cf. 15.25.1 *) |
690 --{* cf. 15.25.1 *} |
711 Ass: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(w,f)\<rightarrow> s1; |
691 Ass: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>va=\<succ>(w,f)\<rightarrow> s1; |
712 G\<turnstile> s1 \<midarrow>e-\<succ>v \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
692 G\<turnstile> s1 \<midarrow>e-\<succ>v \<rightarrow> s2\<rbrakk> \<Longrightarrow> |
713 G\<turnstile>Norm s0 \<midarrow>va:=e-\<succ>v\<rightarrow> assign f v s2" |
693 G\<turnstile>Norm s0 \<midarrow>va:=e-\<succ>v\<rightarrow> assign f v s2" |
714 |
694 |
715 (* cf. 15.24 *) |
695 --{* cf. 15.24 *} |
716 Cond: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e0-\<succ>b\<rightarrow> s1; |
696 Cond: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e0-\<succ>b\<rightarrow> s1; |
717 G\<turnstile> s1 \<midarrow>(if the_Bool b then e1 else e2)-\<succ>v\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
697 G\<turnstile> s1 \<midarrow>(if the_Bool b then e1 else e2)-\<succ>v\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
718 G\<turnstile>Norm s0 \<midarrow>e0 ? e1 : e2-\<succ>v\<rightarrow> s2" |
698 G\<turnstile>Norm s0 \<midarrow>e0 ? e1 : e2-\<succ>v\<rightarrow> s2" |
719 |
699 |
720 |
700 |
721 (* cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5 *) |
701 -- {* The interplay of @{term Call}, @{term Methd} and @{term Body}: |
|
702 Method invocation is split up into these three rules: |
|
703 \begin{itemize} |
|
704 \item [@{term Call}] Calculates the target address and evaluates the |
|
705 arguments of the method, and then performs dynamic |
|
706 or static lookup of the method, corresponding to the |
|
707 call mode. Then the @{term Methd} rule is evaluated |
|
708 on the calculated declaration class of the method |
|
709 invocation. |
|
710 \item [@{term Methd}] A syntactic bridge for the folded method body. |
|
711 It is used by the axiomatic semantics to add the |
|
712 proper hypothesis for recursive calls of the method. |
|
713 \item [@{term Body}] An extra syntactic entity for the unfolded method |
|
714 body was introduced to properly trigger class |
|
715 initialisation. Without class initialisation we |
|
716 could just evaluate the body statement. |
|
717 \end{itemize} |
|
718 *} |
|
719 --{* cf. 15.11.4.1, 15.11.4.2, 15.11.4.4, 15.11.4.5 *} |
722 Call: |
720 Call: |
723 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
721 "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e-\<succ>a'\<rightarrow> s1; G\<turnstile>s1 \<midarrow>args\<doteq>\<succ>vs\<rightarrow> s2; |
724 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
722 D = invocation_declclass G mode (store s2) a' statT \<lparr>name=mn,parTs=pTs\<rparr>; |
725 s3=init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2; |
723 s3=init_lvars G D \<lparr>name=mn,parTs=pTs\<rparr> mode a' vs s2; |
726 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
724 s3' = check_method_access G accC statT mode \<lparr>name=mn,parTs=pTs\<rparr> a' s3; |
727 G\<turnstile>s3' \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s4\<rbrakk> |
725 G\<turnstile>s3' \<midarrow>Methd D \<lparr>name=mn,parTs=pTs\<rparr>-\<succ>v\<rightarrow> s4\<rbrakk> |
728 \<Longrightarrow> |
726 \<Longrightarrow> |
729 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s4)" |
727 G\<turnstile>Norm s0 \<midarrow>{accC,statT,mode}e\<cdot>mn({pTs}args)-\<succ>v\<rightarrow> (restore_lvars s2 s4)" |
730 (* The accessibility check is after init_lvars, to keep it simple. Init_lvars |
728 --{* The accessibility check is after @{term init_lvars}, to keep it simple. |
731 already tests for the absence of a null-pointer reference in case of an |
729 @{term init_lvars} already tests for the absence of a null-pointer |
732 instance method invocation |
730 reference in case of an instance method invocation. |
733 *) |
731 *} |
734 |
732 |
735 Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
733 Methd: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>body G D sig-\<succ>v\<rightarrow> s1\<rbrakk> \<Longrightarrow> |
736 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
734 G\<turnstile>Norm s0 \<midarrow>Methd D sig-\<succ>v\<rightarrow> s1" |
737 (* The local variables l are just a dummy here. The are only used by |
735 |
738 the smallstep semantics *) |
736 Body: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init D\<rightarrow> s1; G\<turnstile>s1 \<midarrow>c\<rightarrow> s2; |
739 (* cf. 14.15, 12.4.1 *) |
737 s3 = (if (\<exists> l. abrupt s2 = Some (Jump (Break l)) \<or> |
740 Body: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init D\<rightarrow> s1; G\<turnstile>s1 \<midarrow>c\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
738 abrupt s2 = Some (Jump (Cont l))) |
741 G\<turnstile>Norm s0 \<midarrow>Body D c |
739 then abupd (\<lambda> x. Some (Error CrossMethodJump)) s2 |
742 -\<succ>the (locals (store s2) Result)\<rightarrow>abupd (absorb Ret) s2" |
740 else s2)\<rbrakk> \<Longrightarrow> |
743 (* The local variables l are just a dummy here. The are only used by |
741 G\<turnstile>Norm s0 \<midarrow>Body D c-\<succ>the (locals (store s2) Result) |
744 the smallstep semantics *) |
742 \<rightarrow>abupd (absorb Ret) s3" |
745 (* evaluation of variables *) |
743 --{* cf. 14.15, 12.4.1 *} |
746 |
744 --{* We filter out a break/continue in @{term s2}, so that we can proof |
747 (* cf. 15.13.1, 15.7.2 *) |
745 definite assignment |
|
746 correct, without the need of conformance of the state. By this the |
|
747 different parts of the typesafety proof can be disentangled a little. *} |
|
748 |
|
749 --{* evaluation of variables *} |
|
750 |
|
751 --{* cf. 15.13.1, 15.7.2 *} |
748 LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
752 LVar: "G\<turnstile>Norm s \<midarrow>LVar vn=\<succ>lvar vn s\<rightarrow> Norm s" |
749 |
753 |
750 (* cf. 15.10.1, 12.4.1 *) |
754 --{* cf. 15.10.1, 12.4.1 *} |
751 FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
755 FVar: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>Init statDeclC\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e-\<succ>a\<rightarrow> s2; |
752 (v,s2') = fvar statDeclC stat fn a s2; |
756 (v,s2') = fvar statDeclC stat fn a s2; |
753 s3 = check_field_access G accC statDeclC fn stat a s2' \<rbrakk> \<Longrightarrow> |
757 s3 = check_field_access G accC statDeclC fn stat a s2' \<rbrakk> \<Longrightarrow> |
754 G\<turnstile>Norm s0 \<midarrow>{accC,statDeclC,stat}e..fn=\<succ>v\<rightarrow> s3" |
758 G\<turnstile>Norm s0 \<midarrow>{accC,statDeclC,stat}e..fn=\<succ>v\<rightarrow> s3" |
755 (* The accessibility check is after fvar, to keep it simple. Fvar already |
759 --{* The accessibility check is after @{term fvar}, to keep it simple. |
756 tests for the absence of a null-pointer reference in case of an instance |
760 @{term fvar} already tests for the absence of a null-pointer reference |
757 field |
761 in case of an instance field |
758 *) |
762 *} |
759 |
763 |
760 (* cf. 15.12.1, 15.25.1 *) |
764 --{* cf. 15.12.1, 15.25.1 *} |
761 AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
765 AVar: "\<lbrakk>G\<turnstile> Norm s0 \<midarrow>e1-\<succ>a\<rightarrow> s1; G\<turnstile>s1 \<midarrow>e2-\<succ>i\<rightarrow> s2; |
762 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
766 (v,s2') = avar G i a s2\<rbrakk> \<Longrightarrow> |
763 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
767 G\<turnstile>Norm s0 \<midarrow>e1.[e2]=\<succ>v\<rightarrow> s2'" |
764 |
768 |
765 |
769 |
766 (* evaluation of expression lists *) |
770 --{* evaluation of expression lists *} |
767 |
771 |
768 (* cf. 15.11.4.2 *) |
772 --{* cf. 15.11.4.2 *} |
769 Nil: |
773 Nil: |
770 "G\<turnstile>Norm s0 \<midarrow>[]\<doteq>\<succ>[]\<rightarrow> Norm s0" |
774 "G\<turnstile>Norm s0 \<midarrow>[]\<doteq>\<succ>[]\<rightarrow> Norm s0" |
771 |
775 |
772 (* cf. 15.6.4 *) |
776 --{* cf. 15.6.4 *} |
773 Cons: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e -\<succ> v \<rightarrow> s1; |
777 Cons: "\<lbrakk>G\<turnstile>Norm s0 \<midarrow>e -\<succ> v \<rightarrow> s1; |
774 G\<turnstile> s1 \<midarrow>es\<doteq>\<succ>vs\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
778 G\<turnstile> s1 \<midarrow>es\<doteq>\<succ>vs\<rightarrow> s2\<rbrakk> \<Longrightarrow> |
775 G\<turnstile>Norm s0 \<midarrow>e#es\<doteq>\<succ>v#vs\<rightarrow> s2" |
779 G\<turnstile>Norm s0 \<midarrow>e#es\<doteq>\<succ>v#vs\<rightarrow> s2" |
776 |
780 |
777 (* Rearrangement of premisses: |
781 (* Rearrangement of premisses: |
778 [0,1(Abrupt),2(Skip),8(Do),4(Lab),30(Nil),31(Cons),27(LVar),17(Cast),18(Inst), |
782 [0,1(Abrupt),2(Skip),8(Jmp),4(Lab),30(Nil),31(Cons),27(LVar),17(Cast),18(Inst), |
779 17(Lit),18(UnOp),19(BinOp),20(Super),21(Acc),3(Expr),5(Comp),25(Methd),26(Body),23(Cond),6(If), |
783 17(Lit),18(UnOp),19(BinOp),20(Super),21(Acc),3(Expr),5(Comp),25(Methd),26(Body),23(Cond),6(If), |
780 7(Loop),11(Fin),9(Throw),13(NewC),14(NewA),12(Init),22(Ass),10(Try),28(FVar), |
784 7(Loop),11(Fin),9(Throw),13(NewC),14(NewA),12(Init),22(Ass),10(Try),28(FVar), |
781 29(AVar),24(Call)] |
785 29(AVar),24(Call)] |
782 *) |
786 *) |
|
787 |
783 ML {* |
788 ML {* |
784 bind_thm ("eval_induct_", rearrange_prems |
789 bind_thm ("eval_induct_", rearrange_prems |
785 [0,1,2,8,4,30,31,27,15,16, |
790 [0,1,2,8,4,30,31,27,15,16, |
786 17,18,19,20,21,3,5,25,26,23,6, |
791 17,18,19,20,21,3,5,25,26,23,6, |
787 7,11,9,13,14,12,22,10,28, |
792 7,11,9,13,14,12,22,10,28, |