1 header {* Communication layer *}
8 subsection {* Messages *}
9 type_synonym actor = nat
12 = ActorName actor -- {* specify an actor *}
13 | Number nat -- {* arbitrary data, as a natural number *}
14 | Signature actor message -- {* an actor's signature for a message *}
15 | Encrypted actor actor message -- {* a message encrypted for two actors *}
16 | MessageList "message list" -- {* a list of messages *}
18 datatype_new message_type
25 fun type_of_message :: "message \<Rightarrow> message_type"
26 where "type_of_message (ActorName _) = ActorNameType"
27 | "type_of_message (Number _) = NumberType"
28 | "type_of_message (Signature _ _) = SignatureType"
29 | "type_of_message (Encrypted _ _ _) = EncryptedType"
30 | "type_of_message (MessageList _) = MessageListType"
32 text {* What are the components of a message, from an omniscient point of view? *}
33 inductive contains_message :: "message \<Rightarrow> message \<Rightarrow> bool"
34 where contains_message_self: "contains_message M M"
35 | contains_message_encrypted:
36 "contains_message M (Encrypted _ _ m) \<Longrightarrow> contains_message M m"
37 | contains_message_list:
38 "m \<in> set ms \<Longrightarrow> contains_message M (MessageList ms)
39 \<Longrightarrow> contains_message M m"
41 text {* If a particular message has been constructed, what other messages must also
42 have been constructed? *}
43 inductive constructed_from :: "message \<Rightarrow> message \<Rightarrow> bool" for M
44 where constructed_from_self: "constructed_from M M"
45 | constructed_from_signature:
46 "constructed_from M (Signature _ m) \<Longrightarrow> constructed_from M m"
47 | constructed_from_encrypted:
48 "constructed_from M (Encrypted _ _ m) \<Longrightarrow> constructed_from M m"
49 | constructed_from_list:
50 "m \<in> set ms \<Longrightarrow> constructed_from M (MessageList ms)
51 \<Longrightarrow> constructed_from M m"
53 lemma actor_name_constructed_from:
54 "constructed_from (ActorName a) m \<Longrightarrow> m = ActorName a"
55 by (induction rule: constructed_from.induct) simp_all
57 lemma number_constructed_from:
58 "constructed_from (Number x) m \<Longrightarrow> m = Number x"
59 by (induction rule: constructed_from.induct) simp_all
61 lemma signature_constructed_from:
62 "constructed_from (Signature a M) m
63 \<Longrightarrow> m = Signature a M \<or> constructed_from M m"
64 proof (induction rule: constructed_from.induct)
65 show "Signature a M = Signature a M \<or> constructed_from M (Signature a M)" by simp
67 assume "Signature b m = Signature a M \<or> constructed_from M (Signature b m)"
68 hence "constructed_from M m"
70 assume "Signature b m = Signature a M"
72 thus "constructed_from M m" by (simp add: constructed_from_self)
74 assume "constructed_from M (Signature b m)"
75 thus "constructed_from M m" by rule
77 thus "m = Signature a M \<or> constructed_from M m" ..
80 assume "Encrypted b c m = Signature a M
81 \<or> constructed_from M (Encrypted b c m)"
82 with constructed_from_encrypted
83 show "m = Signature a M \<or> constructed_from M m"
87 assume "m \<in> set ms"
88 and "MessageList ms = Signature a M
89 \<or> constructed_from M (MessageList ms)"
90 with constructed_from_list show "m = Signature a M \<or> constructed_from M m"
94 lemma encrypted_constructed_from:
95 "constructed_from (Encrypted a b M) m
96 \<Longrightarrow> m = Encrypted a b M \<or> constructed_from M m"
97 proof (induction rule: constructed_from.induct)
98 case constructed_from_self
99 show "Encrypted a b M = Encrypted a b M
100 \<or> constructed_from M (Encrypted a b M)"
103 case (constructed_from_signature c m)
104 from constructed_from_signature.IH have "constructed_from M (Signature c m)"
106 hence "constructed_from M m" by rule
107 thus "m = Encrypted a b M \<or> constructed_from M m" ..
109 case (constructed_from_encrypted c d m)
110 from constructed_from_encrypted.IH have "constructed_from M m"
112 assume "Encrypted c d m = Encrypted a b M"
113 thus "constructed_from M m" by (simp add: constructed_from_self)
115 assume "constructed_from M (Encrypted c d m)"
116 thus "constructed_from M m" by rule
118 thus "m = Encrypted a b M \<or> constructed_from M m" ..
120 case (constructed_from_list m ms)
121 from constructed_from_list.IH have "constructed_from M (MessageList ms)"
123 with constructed_from_list.hyps(1) have "constructed_from M m" by rule
124 thus "m = Encrypted a b M \<or> constructed_from M m" ..
127 lemma list_constructed_from:
128 "constructed_from (MessageList ms) m
129 \<Longrightarrow> m = MessageList ms \<or> (\<exists> M \<in> set ms. constructed_from M m)"
130 proof (induction rule: constructed_from.induct)
131 case constructed_from_self
132 show "MessageList ms = MessageList ms
133 \<or> (\<exists> M \<in> set ms. constructed_from M (MessageList ms))"
136 case (constructed_from_signature a m)
137 from constructed_from_signature.IH
138 have "\<exists> M \<in> set ms. constructed_from M (Signature a m)"
140 hence "\<exists> M \<in> set ms. constructed_from M m"
141 by (metis constructed_from.constructed_from_signature)
142 thus "m = MessageList ms \<or> (\<exists> M \<in> set ms. constructed_from M m)" ..
144 case (constructed_from_encrypted a b m)
145 from constructed_from_encrypted.IH
146 have "\<exists> M \<in> set ms. constructed_from M (Encrypted a b m)"
148 hence "\<exists> M \<in> set ms. constructed_from M m"
149 by (metis constructed_from.constructed_from_encrypted)
150 thus "m = MessageList ms \<or> (\<exists> M \<in> set ms. constructed_from M m)" ..
152 case (constructed_from_list m ms')
153 from constructed_from_list.IH have "\<exists> M \<in> set ms. constructed_from M m"
155 assume "MessageList ms' = MessageList ms"
156 with `m \<in> set ms'` have "m \<in> set ms" by simp
157 with constructed_from_self show "\<exists> M \<in> set ms. constructed_from M m"
160 assume "\<exists> M \<in> set ms. constructed_from M (MessageList ms')"
161 with `m \<in> set ms'` show "\<exists> M \<in> set ms. constructed_from M m"
162 by (metis constructed_from.constructed_from_list)
164 thus "m = MessageList ms \<or> (\<exists> M \<in> set ms. constructed_from M m)" ..
167 lemma constructed_from_transitive:
168 assumes "constructed_from M' M"
169 shows "constructed_from M m \<Longrightarrow> constructed_from M' m"
170 proof (induction rule: constructed_from.induct)
171 case constructed_from_self
172 from assms show "constructed_from M' M" .
174 case (constructed_from_signature a m)
175 from constructed_from_signature.IH show "constructed_from M' m" by rule
177 case (constructed_from_encrypted a b m)
178 from constructed_from_encrypted.IH show "constructed_from M' m" by rule
180 case (constructed_from_list m ms)
181 from constructed_from_list.hyps(1) and constructed_from_list.IH
182 show "constructed_from M' m" by rule
185 text {* What can a particular actor learn from a particular message? *}
186 inductive learnable :: "actor \<Rightarrow> message \<Rightarrow> message \<Rightarrow> bool" for a M
187 where identity_learnable: "learnable a M M"
188 -- {* the message itself *}
189 | encrypted1_learnable: "learnable a M (Encrypted a _ m) \<Longrightarrow> learnable a M m"
190 | encrypted2_learnable: "learnable a M (Encrypted _ a m) \<Longrightarrow> learnable a M m"
191 -- {* the body of a learnable message encrypted for the actor *}
193 "m \<in> set l \<Longrightarrow> learnable a M (MessageList l) \<Longrightarrow> learnable a M m"
194 -- {* any element of a learnable list of messages *}
196 lemma learnable_implies_constructed_from:
197 "learnable a M m \<Longrightarrow> constructed_from M m"
198 proof (induction rule: learnable.induct)
199 show "constructed_from M M" by rule
201 { assume "constructed_from M (Encrypted a b m)"
202 thus "constructed_from M m" by rule
204 assume "constructed_from M (Encrypted b a m)"
205 thus "constructed_from M m" by rule
209 assume "m \<in> set ms" and "constructed_from M (MessageList ms)"
210 thus "constructed_from M m" by rule
213 text {* What messages can a particular actor construct from a particular set of
215 inductive constructible :: "actor \<Rightarrow> message set \<Rightarrow> message \<Rightarrow> bool" for a Ms
216 where learnable_constructible:
217 "M \<in> Ms \<Longrightarrow> learnable a M m \<Longrightarrow> constructible a Ms m"
218 -- {* any message learnable from any message in the set *}
219 | actorName_constructible: "constructible a Ms (ActorName _)"
220 -- {* any actor's name *}
221 | number_constructible: "constructible a Ms (Number _)"
223 | signed_constructible:
224 "constructible a Ms m \<Longrightarrow> constructible a Ms (Signature a m)"
225 -- {* an otherwise constructible message, signed by this actor *}
226 | encrypted_constructible:
227 "constructible a Ms m \<Longrightarrow> constructible a Ms (Encrypted _ _ m)"
228 -- {* an otherwise constructible message, encrypted to any pair of actors *}
229 | listed_constructible:
230 "(\<forall> m \<in> set l. constructible a Ms m)
231 \<Longrightarrow> constructible a Ms (MessageList l)"
232 -- {* a list of otherwise constructible messages *}
234 subsubsection {* Indistinguishability of messages *}
235 datatype_new agent = CommunicationLayer | Actor actor
237 text {* What pairs of messages should we not expect a particular agent to be able
238 to distinguish between, given a particular set of messages to work from?
239 This definition isn't intended to express a limit on what an attacker might
240 be able to do; rather, it's meant to limit what we might reasonably expect
241 an honest agent to be able to do without resorting to sophisticated
242 cryptanalysis or anything similarly difficult. *}
243 inductive indistinguishable :: "agent \<Rightarrow> message set \<Rightarrow> message \<Rightarrow> message \<Rightarrow> bool"
244 where "indistinguishable CommunicationLayer _ _ _"
245 | "indistinguishable _ _ m m"
246 | "\<not> constructible a Ms m \<Longrightarrow> \<not> constructible a Ms m'
247 \<Longrightarrow> indistinguishable (Actor a) Ms (Signature _ m) (Signature _ m')"
248 | "indistinguishable A Ms m m'
249 \<Longrightarrow> indistinguishable A Ms (Signature a m) (Signature a m')"
250 | "A \<noteq> Actor a \<Longrightarrow> A \<noteq> Actor b \<Longrightarrow> A \<noteq> Actor c \<Longrightarrow> A \<noteq> Actor d
251 \<Longrightarrow> indistinguishable A _ (Encrypted a b _) (Encrypted c d _)"
252 | "indistinguishable A Ms m m'
253 \<Longrightarrow> indistinguishable A Ms (Encrypted a b m) (Encrypted a b m')"
254 | "indistinguishable A Ms m m'
255 \<Longrightarrow> indistinguishable A Ms (MessageList ms) (MessageList ms')
256 \<Longrightarrow> indistinguishable A Ms
257 (MessageList (m # ms))
258 (MessageList (m' # ms'))"
260 lemma indistinguishable_symmetric:
261 "indistinguishable A Ms m m' \<Longrightarrow> indistinguishable A Ms m' m"
262 proof (induction rule: indistinguishable.induct)
264 show "indistinguishable CommunicationLayer Ms m m'" by rule
266 show "indistinguishable A Ms m m" by rule
268 assume "\<not> constructible a Ms m'" and "\<not> constructible a Ms m"
269 thus "indistinguishable (Actor a) Ms (Signature c m') (Signature b m)" by rule
272 assume "indistinguishable A Ms m' m"
273 thus "indistinguishable A Ms (Signature a m') (Signature a m)" by rule
275 fix A Ms m m' a b c d
276 assume "A \<noteq> Actor c" and "A \<noteq> Actor d" and "A \<noteq> Actor a" and "A \<noteq> Actor b"
277 thus "indistinguishable A Ms (Encrypted c d m') (Encrypted a b m)" by rule
280 assume "indistinguishable A Ms m' m"
281 thus "indistinguishable A Ms (Encrypted a b m') (Encrypted a b m)" by rule
284 assume "indistinguishable A Ms m' m"
285 and "indistinguishable A Ms (MessageList ms') (MessageList ms)"
286 thus "indistinguishable A Ms (MessageList (m' # ms')) (MessageList (m # ms))"
290 definition indistinguishability_map ::
291 "agent \<Rightarrow> message set \<Rightarrow> (message \<Rightarrow> message) \<Rightarrow> bool" where
292 "indistinguishability_map A Ms f
293 \<longleftrightarrow> bij f
294 \<and> (\<forall> m. indistinguishable A Ms m (f m)
295 \<and> (\<forall> a b. (A = Actor a \<and> constructible a Ms m
296 \<longrightarrow> f (Signature b m) = Signature b (f m)
298 \<and> (A = Actor a \<or> A = Actor b
299 \<longrightarrow> f (Encrypted a b m) = Encrypted a b (f m)
303 \<and> (A \<noteq> CommunicationLayer
304 \<longrightarrow> (\<forall> ms. f (MessageList ms) = MessageList (map f ms))
307 lemma learnable_indistinguishability_map:
308 assumes im: "indistinguishability_map (Actor a) Ms f"
309 shows "learnable a M m \<Longrightarrow> learnable a (f M) (f m)"
310 proof (induction rule: learnable.induct)
311 show "learnable a (f M) (f M)" by rule
313 assume "learnable a (f M) (f (Encrypted a b m))"
315 from im have "f (Encrypted a b m) = Encrypted a b (f m)"
316 by (unfold indistinguishability_map_def) simp
317 ultimately show "learnable a (f M) (f m)" by (metis encrypted1_learnable)
320 assume "learnable a (f M) (f (Encrypted b a m))"
322 from im have "f (Encrypted b a m) = Encrypted b a (f m)"
323 by (unfold indistinguishability_map_def) simp
324 ultimately show "learnable a (f M) (f m)" by (metis encrypted2_learnable)
327 assume minms: "m \<in> set ms"
328 and learnablefms: "learnable a (f M) (f (MessageList ms))"
329 from minms have fminfms: "f m \<in> set (map f ms)" by simp
330 from im have "f (MessageList ms) = MessageList (map f ms)"
331 by (unfold indistinguishability_map_def) simp
332 with fminfms and learnablefms show "learnable a (f M) (f m)"
333 by (metis listed_learnable)
336 lemma indistinguishable_message_type:
337 "indistinguishable (Actor a) Ms m m' \<Longrightarrow> type_of_message m = type_of_message m'"
338 proof (induction rule: indistinguishable.cases)
339 assume "Actor a = CommunicationLayer"
340 thus "type_of_message m = type_of_message m'" ..
343 assume "m = n" and "m' = n"
344 thus "type_of_message m = type_of_message m'" by simp
347 assume "m = Signature b n" and "m' = Signature c n'"
348 thus "type_of_message m = type_of_message m'" by simp
349 thus "type_of_message m = type_of_message m'" .
352 assume "m = Encrypted b c n" and "m' = Encrypted d e n'"
353 thus "type_of_message m = type_of_message m'" by simp
354 thus "type_of_message m = type_of_message m'" .
357 assume "m = MessageList (n # ns)" and "m' = MessageList (n' # ns')"
358 thus "type_of_message m = type_of_message m'" by simp
361 lemma learnable_inverse_indistinguishability_map:
362 assumes im: "indistinguishability_map (Actor a) Ms f"
363 shows "learnable a M m \<Longrightarrow> learnable a (inv f M) (inv f m)"
364 proof (induction rule: learnable.induct)
365 from im have bij: "bij f" unfolding indistinguishability_map_def ..
366 { show "learnable a (inv f M) (inv f M)" by rule
368 assume "learnable a (inv f M) (inv f (Encrypted a b m))"
370 { from im have "f (Encrypted a b (inv f m)) = Encrypted a b (f (inv f m))"
371 by (unfold indistinguishability_map_def) simp
372 also from bij have "\<dots> = Encrypted a b m" by simp
373 finally have "inv f (Encrypted a b m) = Encrypted a b (inv f m)"
376 ultimately have "learnable a (inv f M) (Encrypted a b (inv f m))" by simp
377 thus "learnable a (inv f M) (inv f m)" by rule
380 assume "learnable a (inv f M) (inv f (Encrypted b a m))"
382 { from im have "f (Encrypted b a (inv f m)) = Encrypted b a (f (inv f m))"
383 by (unfold indistinguishability_map_def) simp
384 also from bij have "\<dots> = Encrypted b a m" by simp
385 finally have "inv f (Encrypted b a m) = Encrypted b a (inv f m)"
388 ultimately have "learnable a (inv f M) (Encrypted b a (inv f m))" by simp
389 thus "learnable a (inv f M) (inv f m)" by rule
392 assume minms: "m \<in> set ms"
393 and learnableinvfms: "learnable a (inv f M) (inv f (MessageList ms))"
394 from minms have invfmininvfms: "inv f m \<in> set (map (inv f) ms)" by simp
396 "f (MessageList (map (inv f) ms)) = MessageList (map f (map (inv f) ms))"
397 by (unfold indistinguishability_map_def) simp
398 also from bij have "\<dots> = MessageList ms"
399 by (subst bij_map_f_map_inv_f) simp_all
400 finally have "inv f (MessageList ms) = MessageList (map (inv f) ms)"
402 with invfmininvfms and learnableinvfms show "learnable a (inv f M) (inv f m)"
403 by (metis listed_learnable)
407 type_synonym encrypted_message_data = "actor \<times> actor \<times> message"
409 encrypted_message_map = "encrypted_message_data \<Rightarrow> encrypted_message_data"
411 subsection {* Events *}
412 type_synonym payment = nat
415 = Construct actor message -- {* an actor constructs a message *}
416 | Send actor actor message -- {* send a message from one actor to another *}
417 | Receive actor message -- {* an actor receives a message *}
421 payment -- {* specifies amount and manner of payment *}
422 nat -- {* payment id, intended to be unique to payer/payee pair*}
424 text {* Given a set of past events, which messages has a particular actor received? *}
425 definition messages_received :: "actor \<Rightarrow> event set \<Rightarrow> message set"
426 where "messages_received a es = {m. Receive a m \<in> es}"
428 text {* What can a particular agent do, given a set of past events and a set of
429 concurrent events? *}
430 inductive doable :: "agent \<Rightarrow> event set \<Rightarrow> event set \<Rightarrow> event \<Rightarrow> bool"
431 where communicationLayer_transmit_doable:
432 "(Send _ _ m) \<in> es \<Longrightarrow> doable CommunicationLayer es _ (Receive _ m)"
433 -- {* the communication layer can cause anyone to receive any message
434 previously sent by anyone to anyone *}
435 | construct_actor_name: "doable (Actor a) _ _ (Construct a (ActorName _))"
436 -- {* an actor can construct any actor's name *}
437 | construct_number: "doable (Actor a) _ _ (Construct a (Number _))"
438 -- {* an actor can construct any number *}
439 | construct_signature:
440 "Construct a m \<in> es \<union> es'
441 \<Longrightarrow> doable (Actor a) es es' (Construct a (Signature a m))"
442 -- {* an actor can construct their own signature for a message they've
444 | construct_encrypted:
445 "Construct a m \<in> es \<union> es'
446 \<Longrightarrow> doable (Actor a) es es' (Construct a (Encrypted _ _ m))"
447 -- {* an actor can construct an encrypted version of a message they've
450 "\<forall> m \<in> set ms. Construct a m \<in> es \<union> es'
451 \<Longrightarrow> doable (Actor a) es es' (Construct a (MessageList ms))"
452 -- {* an actor can construct a list of messages they've constructed *}
453 | construct_received:
454 "Receive a M \<in> es \<Longrightarrow> learnable a M m
455 \<Longrightarrow> doable (Actor a) es _ (Construct a m)"
456 -- {* an actor can construct a message they can learn from one they've
457 previously received *}
458 | constructed_sendable:
459 "Construct a m \<in> es \<union> es' \<Longrightarrow> doable (Actor a) es es' (Send a _ m)"
460 -- {* an actor can send any message they've constructed *}
461 | pay_doable: "doable (Actor a) _ _ (Pay a _ _ _)"
462 -- {* an actor can always pay anyone any amount with any payment id *}
464 text {* Which agent must have caused a particular event? *}
465 fun causal_agent :: "event \<Rightarrow> agent"
466 where construct_cause: "causal_agent (Construct a _) = Actor a"
467 | send_cause: "causal_agent (Send a _ _) = Actor a"
468 | receive_cause: "causal_agent (Receive _ _) = CommunicationLayer"
469 | pay_cause: "causal_agent (Pay a _ _ _) = Actor a"
471 text {* If an event is doable by an agent, then that agent must be the causal one *}
472 lemma doable_implies_causal:
473 assumes "doable a es es' e"
474 shows "causal_agent e = a"
475 using assms by (cases rule: doable.cases) simp_all
477 text {* Which events affect a particular agent? *}
478 inductive affected_agent :: "agent \<Rightarrow> event \<Rightarrow> bool"
479 where constructor_affected: "affected_agent (Actor a) (Construct a _)"
480 | sender_affected: "affected_agent (Actor a) (Send a _ _)"
481 | send_affects_communication:
482 "affected_agent CommunicationLayer (Send _ _ _)"
483 | receiver_affected: "affected_agent (Actor a) (Receive a _)"
484 | receive_affects_communication:
485 "affected_agent CommunicationLayer (Receive _ _)"
486 | payer_affected: "affected_agent (Actor a) (Pay a _ _ _)"
487 | payee_affected: "affected_agent (Actor a) (Pay _ a _ _)"
489 text {* The causal agent is always affected *}
490 lemma causal_affected: "affected_agent (causal_agent e) e"
491 by (cases rule: causal_agent.induct) (simp_all add: affected_agent.simps)
493 fun lift_message_map_event
494 :: "(message \<Rightarrow> message) \<Rightarrow> event \<Rightarrow> event"
495 where "lift_message_map_event f (Construct a m) = Construct a (f m)"
496 | "lift_message_map_event f (Send a b m) = Send a b (f m)"
497 | "lift_message_map_event f (Receive a m) = Receive a (f m)"
498 | "lift_message_map_event _ e = e"
500 lemma sendable'_implies_sendable:
501 assumes sendable': "Send a b M' \<in> image (lift_message_map_event f) es"
502 shows "\<exists> M. f M = M' \<and> Send a b M \<in> es"
504 from sendable' obtain e
505 where ein: "e \<in> es" and mape: "lift_message_map_event f e = Send a b M'"
508 obtain M where esend: "e = Send a b M" and mapM: "f M = M'"
509 by (cases e) simp_all
510 from esend and ein have sendable: "Send a b M \<in> es" by simp
511 from mapM and sendable show "\<exists> M. f M = M' \<and> Send a b M \<in> es" by auto
514 subsection {* Histories *}
515 type_synonym time = nat
516 type_synonym history = "(event \<times> time) set"
518 text {* What events occurred before a given time? *}
519 definition events_before :: "history \<Rightarrow> time \<Rightarrow> event set" where
520 "events_before h t = {e. \<exists> u < t. (e, u) \<in> h}"
522 lemma events_before_monotonic:
524 shows "events_before h t' \<subseteq> events_before h t"
527 assume "e \<in> events_before h t'"
528 then obtain t'' where t''t': "t'' < t'" and inh: "(e, t'') \<in> h"
529 by (unfold events_before_def) auto
530 from t''t' and assms have "t'' < t" by simp
531 with inh show "e \<in> events_before h t" by (unfold events_before_def) auto
534 text {* What events occurred at a given time? *}
535 definition events_at :: "history \<Rightarrow> time \<Rightarrow> event set" where
536 "events_at h t = {e. (e, t) \<in> h}"
538 abbreviation events_not_after :: "history \<Rightarrow> time \<Rightarrow> event set" where
539 "events_not_after h t == events_before h t \<union> events_at h t"
541 lemma events_not_after: "e \<in> events_not_after h t \<longleftrightarrow> (\<exists> t' \<le> t. (e, t') \<in> h)"
543 assume "e \<in> events_not_after h t"
544 hence "e \<in> events_before h t \<or> e \<in> events_at h t" by simp
545 thus "\<exists> t' \<le> t. (e, t') \<in> h"
547 assume "e \<in> events_before h t"
548 then obtain t' where "t' < t" and "(e, t') \<in> h"
549 by (unfold events_before_def) auto
550 thus "\<exists> t' \<le> t. (e, t') \<in> h" by (simp add: exI[of _ t'])
552 assume "e \<in> events_at h t"
553 thus "\<exists> t' \<le> t. (e, t') \<in> h" by (unfold events_at_def) (simp add: exI[of _ t])
556 assume "\<exists> t' \<le> t. (e, t') \<in> h"
557 then obtain t' where t't: "t' \<le> t" and inh: "(e, t') \<in> h" by auto
558 show "e \<in> events_not_after h t"
561 with inh show "e \<in> events_not_after h t" by (unfold events_at_def) simp
563 assume "t' \<noteq> t"
564 with t't have "t' < t" by simp
565 with inh show "e \<in> events_not_after h t" by (unfold events_before_def) auto
569 lemma events_not_after_monotonic:
571 shows "events_not_after h t' \<subseteq> events_not_after h t"
574 assume "e \<in> events_not_after h t'"
575 with events_not_after obtain t'' where t''t': "t'' \<le> t'" and inh: "(e, t'') \<in> h"
577 from t''t' and assms have "t'' \<le> t" by simp
578 with inh and events_not_after show "e \<in> events_not_after h t" by auto
581 text {* Which histories could possibly occur? *}
582 definition possible_history :: "history \<Rightarrow> bool" where
583 "possible_history h \<longleftrightarrow>
584 (\<forall> (e, t) \<in> h. doable (causal_agent e) (events_before h t) (events_at h t) e)"
586 text {* What messages did a given agent receive before a given time? *}
587 fun messages_received_before :: "agent \<Rightarrow> history \<Rightarrow> time \<Rightarrow> message set"
588 where "messages_received_before CommunicationLayer _ _ = {}"
589 | "messages_received_before (Actor a) h t
590 = {m. Receive a m \<in> events_before h t}"
592 text {* What subhistory is relevant to a given agent before a given time? *}
593 definition relevant_subhistory :: "agent \<Rightarrow> time \<Rightarrow> history \<Rightarrow> history" where
594 "relevant_subhistory A t h = {(e, t') \<in> h. affected_agent A e \<and> t' < t}"