Last active
June 23, 2025 13:06
-
-
Save gterzian/fb2d98d4e89a3d7dcd84b471fbbb5bf7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ----------------------- MODULE ImageCacheThree ----------------------- | |
| EXTENDS FiniteSets, Integers, Sequences | |
| CONSTANT N | |
| VARIABLES image_states, image_queue, keys_used, keys, keys_batch | |
| ----------------------------------------------------------------------------- | |
| Image == 1..N | |
| ImageState == {"None", "PendingKey", "HasKey", "Loaded"} | |
| TypeOk == /\ image_states \in [Image -> ImageState] | |
| /\ image_queue \in Seq(Image) | |
| /\ keys_used \in Int | |
| /\ keys \in Seq({"Generated"}) | |
| /\ keys_batch \in BOOLEAN | |
| ----------------------------------------------------------------------------- | |
| Init == /\ image_states = [i \in Image |-> "None"] | |
| /\ image_queue = <<>> | |
| /\ keys_used = 0 | |
| /\ keys = <<>> | |
| /\ keys_batch = FALSE | |
| StartLoad(i) == /\ image_states[i] = "None" | |
| /\ image_states' = [image_states EXCEPT ![i] = "PendingKey"] | |
| /\ image_queue' = Append(image_queue, i) | |
| /\ UNCHANGED<<keys_used, keys, keys_batch>> | |
| GenerateKeys == LET | |
| keys_requested == Cardinality({i \in Image: image_states[i] = "PendingKey"}) | |
| keys_needed == keys_requested - Len(keys) | |
| batch == [i \in 1..keys_needed |-> "Generated"] | |
| IN | |
| /\ keys' = IF keys_needed > 0 THEN keys \o batch ELSE keys | |
| /\ keys_batch' = TRUE | |
| /\ UNCHANGED<<image_states, image_queue, keys_used>> | |
| SetKey(i) == /\ Len(keys) > 0 | |
| /\ keys_batch = TRUE | |
| /\ keys' = Tail(keys) | |
| /\ Head(image_queue) = i | |
| /\ image_states[i] = "PendingKey" | |
| /\ image_states' = [image_states EXCEPT ![i] = "HasKey"] | |
| /\ keys_used' = keys_used + 1 | |
| /\ UNCHANGED<<image_queue, keys_batch>> | |
| FinishLoad(i) == /\ image_states[i] = "HasKey" | |
| /\ Head(image_queue) = i | |
| /\ image_states' = [image_states EXCEPT ![i] = "Loaded"] | |
| /\ UNCHANGED<<image_queue, keys_used, keys, keys_batch>> | |
| DequeImage(i) == /\ Len(image_queue) > 0 | |
| /\ image_states[i] = "Loaded" | |
| /\ Head(image_queue) = i | |
| /\ image_queue' = Tail(image_queue) | |
| \*/\ keys' = <<>> | |
| /\ keys_batch' = FALSE | |
| /\ UNCHANGED<<image_states, keys_used, keys>> | |
| Done == /\ \A ii \in Image: image_states[ii] = "Loaded" | |
| /\ UNCHANGED<<image_states, image_queue, keys_used, keys, keys_batch>> | |
| Next == \/ \E i \in Image: \/ StartLoad(i) | |
| \/ FinishLoad(i) | |
| \/ DequeImage(i) | |
| \/ SetKey(i) | |
| \/ Done | |
| \/ GenerateKeys | |
| ----------------------------------------------------------------------------- | |
| BatchingSpec == Init /\ [][Next]_<<image_states, image_queue, keys_used, keys, keys_batch>> | |
| StateBar[i \in Image] == CASE image_states[i] \in {"Loaded", "None"} -> image_states[i] | |
| [] Len(image_queue) > 0 /\ Head(image_queue) = i -> image_states[i] | |
| [] OTHER -> "None" | |
| KeysUsedBar == LET | |
| front_image_has_key == Len(image_queue) > 0 /\ image_states[Head(image_queue)] = "HasKey" | |
| images_loaded == Cardinality({i \in Image: image_states[i] \in {"Loaded"}}) | |
| IN | |
| IF front_image_has_key THEN 1 + images_loaded | |
| ELSE images_loaded | |
| KeysBar == IF | |
| /\ Len(keys) > 0 | |
| /\ image_states[Head(image_queue)] = "PendingKey" | |
| /\ keys_batch = TRUE THEN "Generated" | |
| ELSE "Empty" | |
| Bar == INSTANCE ImageCacheTwo | |
| WITH image_states <- StateBar, | |
| keys_used <- KeysUsedBar, | |
| keys <- KeysBar | |
| BarSpec == Bar!NonBlockingSpec | |
| ============================================================================= |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment