text‹Sumarr computes the combined sum of all the elements of
arrays. It does this by running a number of threads in
, each computing the sum of elements of one of the arrays,
then adding the result to a global variable gsum shared by all threads. › record sumarr_state =
― ‹local variables of threads›
tarr :: "routine ==> word32 array"
tid :: "routine ==> word32"
ti :: "routine ==> word32"
tsum :: "routine ==> word32"
― ‹global variables›
glock :: nat
gsum :: word32
gdone :: word32
garr :: "(word32 array) array"
― ‹ghost variables›
ghost_lock :: "routine ==> bool"
definition "tarr_inv s i ≡ length (tarr s i) = unat NSUM ∧ tarr s i = garr s ! i"
abbreviation "sumarr_inv_till_lock s i ≡¬ bit (gdone s) i ∧ ((¬ (ghost_lock s) (1 - i)) ⟶ ((gdone s = 0 ∧ gsum s = 0) ∨ (bit (gdone s) (1 - i) ∧ gsum s = local_sum (garr s !(1 - i)))))"
abbreviation "lock_inv s ≡ (glock s = fromEnum (ghost_lock s 0) + fromEnum (ghost_lock s 1)) ∧ (¬(ghost_lock s) 0 ∨¬(ghost_lock s) 1)"
abbreviation "garr_inv s i ≡ (∃a b. garr s = [a, b]) ∧ length (garr s ! (1-i)) = unat NSUM"
abbreviation "sumarr_inv s i ≡ lock_inv s ∧ tarr_inv s i ∧ garr_inv s i ∧ tid s i = (of_nat i + 1)"
definition
lock :: "routine ==> (sumarr_state, funcs, faults) ann_com" where "lock i ≡ {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋sumarr_inv_till_lock i} AWAIT 🍋glock = 0 THEN 🍋glock:=1,, 🍋ghost_lock:=🍋ghost_lock (i:= True) END"
definition "sumarr_in_lock1 s i ≡¬bit (gdone s) i ∧ ((gdone s = 0 ∧ gsum s = local_sum (tarr s i)) ∨ (bit (gdone s) (1 - i) ∧¬ bit (gdone s) i ∧ gsum s = global_sum (garr s)))"
definition "sumarr_in_lock2 s i ≡ (bit (gdone s) i ∧¬ bit (gdone s) (1 - i) ∧ gsum s = local_sum (tarr s i)) ∨ (bit (gdone s) i ∧ bit (gdone s) (1 - i) ∧ gsum s = global_sum (garr s))"
definition
unlock :: "routine ==> (sumarr_state, funcs, faults) ann_com" where "unlock i ≡ {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋glock = 1 ∧ 🍋ghost_lock i ∧ bit 🍋gdone (unat (🍋tid i - 1)) ∧🍋sumarr_in_lock2 i } ⟨🍋glock := 0,, 🍋ghost_lock:=🍋ghost_lock (i:= False)⟩"
definition "local_postcond s i ≡ (¬ (ghost_lock s) (1 - i) ⟶ gsum s = (if bit (gdone s) 0 ∧ bit (gdone s) 1 then global_sum (garr s) else local_sum (garr s ! i))) ∧ bit (gdone s) i ∧¬ghost_lock s i"
definition
sumarr :: "routine ==> (sumarr_state, funcs, faults) ann_com" where "sumarr i ≡ {🍋sumarr_inv i ∧🍋sumarr_inv_till_lock i} 🍋tsum:=🍋tsum(i:=0) ;; {🍋tsum i = 0 ∧🍋sumarr_inv i ∧🍋sumarr_inv_till_lock i} 🍋ti:=🍋ti(i:=0) ;; TRY {🍋tsum i = 0 ∧🍋sumarr_inv i ∧🍋ti i = 0 ∧🍋sumarr_inv_till_lock i} WHILE 🍋ti i < NSUM INV {🍋sumarr_inv i ∧🍋ti i ≤ NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (take (unat (🍋ti i)) (🍋tarr i)) ∧🍋sumarr_inv_till_lock i} DO {🍋sumarr_inv i ∧🍋ti i < NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (take (unat (🍋ti i)) (🍋tarr i)) ∧🍋sumarr_inv_till_lock i} (InvalidMem, { array_in_bound (🍋tarr i) (🍋ti i) }) ⟼ {🍋sumarr_inv i ∧🍋ti i < NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (take (unat (🍋ti i)) (🍋tarr i)) ∧🍋sumarr_inv_till_lock i} 🍋tsum:=🍋tsum(i:=🍋tsum i + array_nth (🍋tarr i) (🍋ti i));; {🍋sumarr_inv i ∧🍋ti i < NSUM ∧ local_sum (take (unat (🍋ti i)) (🍋tarr i)) ≤ MAXSUM ∧ (🍋tsum i < MAXSUM ∧ array_nth (🍋tarr i) (🍋ti i) < MAXSUM ⟶ 🍋tsum i = local_sum (take (Suc (unat (🍋ti i))) (🍋tarr i))) ∧ (array_nth (🍋tarr i) (🍋ti i) ≥ MAXSUM ∨🍋tsum i ≥ MAXSUM⟶ local_sum (🍋tarr i) = MAXSUM) ∧ 🍋sumarr_inv_till_lock i } (InvalidMem, { array_in_bound (🍋tarr i) (🍋ti i) }) ⟼ {🍋sumarr_inv i ∧🍋ti i < NSUM ∧ (🍋tsum i < MAXSUM ∧ array_nth (🍋tarr i) (🍋ti i) < MAXSUM ⟶ 🍋tsum i = local_sum (take (Suc (unat (🍋ti i))) (🍋tarr i))) ∧ (array_nth (🍋tarr i) (🍋ti i) ≥ MAXSUM ∨🍋tsum i ≥ MAXSUM ⟶ local_sum (🍋tarr i) = MAXSUM) ∧ 🍋sumarr_inv_till_lock i} IF array_nth (🍋tarr i) (🍋ti i) ≥ MAXSUM ∨🍋tsum i ≥ MAXSUM THEN {🍋sumarr_inv i ∧🍋ti i < NSUM ∧ local_sum (🍋tarr i) = MAXSUM ∧🍋sumarr_inv_till_lock i} 🍋tsum:=🍋tsum(i:=MAXSUM);; {🍋sumarr_inv i ∧🍋ti i < NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (🍋tarr i) ∧🍋sumarr_inv_till_lock i } THROW ELSE {🍋sumarr_inv i ∧🍋ti i < NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (take (Suc (unat (🍋ti i))) (🍋tarr i)) ∧🍋sumarr_inv_till_lock i} SKIP FI;; {🍋sumarr_inv i ∧🍋ti i < NSUM ∧🍋tsum i ≤ MAXSUM ∧ 🍋tsum i = local_sum (take (Suc (unat (🍋ti i))) (🍋tarr i)) ∧🍋sumarr_inv_till_lock i } 🍋ti:=🍋ti(i:=🍋ti i + 1) OD CATCH {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋sumarr_inv_till_lock i} SKIP END;; {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋sumarr_inv_till_lock i} SCALL (''lock'', i) 0;; {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋glock = 1 ∧ 🍋ghost_lock i ∧🍋sumarr_inv_till_lock i } 🍋gsum:=🍋gsum + 🍋tsum i ;; {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋glock = 1 ∧ 🍋ghost_lock i ∧🍋sumarr_in_lock1 i } 🍋gdone:=(🍋gdone OR 🍋tid i) ;; {🍋sumarr_inv i ∧🍋tsum i = local_sum (🍋tarr i) ∧🍋glock = 1 ∧ 🍋ghost_lock i ∧ bit 🍋gdone (unat (🍋tid i - 1)) ∧🍋sumarr_in_lock2 i } SCALL (''unlock'', i) 0"
lemma pre_call_sumarr: "i < 2 ==> precond x ==> x ∈ pre (ann (call_sumarr i))" unfolding precond_def call_sumarr_def ann_call_def by (fastforce dest: less_2_cases simp: array_length_def)
lemma post_call_sumarr: "local_postcond x 0 ==> local_postcond x 1 ==> postcond x" unfolding postcond_def local_postcond_def by (fastforce dest: less_2_cases split: if_splits)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.