specification and verification of multithreaded object
play

Specification and Verification of Multithreaded Object-Oriented - PowerPoint PPT Presentation

Specification and Verification of Multithreaded Object-Oriented Programs with Separation Logic Cl ement Hurlin INRIA Sophia Antipolis M editerran ee, France Universiteit Twente, The Netherlands Soutenance de th` ese Th` ese


  1. Hoare rules for fork and join class Thread extends Object{ pred preFork = true; pred postJoin<perm p> = true; requires preFork; ensures true; void fork(); requires Join(this,p); ensures postJoin<p>; void join(); requires preFork; ensures postJoin<1>; void run() { null } } ë We parameterize Join and postJoin by a permission. Join(t,p) give access to fraction p of thread t ’s postcondition. 16

  2. Hoare rules for fork and join class Thread extends Object{ pred preFork = true; group postJoin = true; requires preFork; ensures true; void fork(); requires Join(this,p); ensures postJoin<p>; void join(); requires preFork; ensures postJoin<1>; void run() { null } } For soundness: postJoin is a special predicate: a group. ë It satisfies ❅ perm p . postJoin<p> *-* (postJoin<p ④ 2>*postJoin<p ④ 2>) . 17

  3. Objective 2: reentrant locks [APLAS’08] Reentrant locks are the main primitive to acquire/release locks in Java. They can be acquired more than once (and released accordingly) ë Convenient for programmers (no need to acquire conditionally) 18

  4. Objective 2: reentrant locks [APLAS’08] Reentrant locks are the main primitive to acquire/release locks in Java. They can be acquired more than once (and released accordingly) ë Convenient for programmers (no need to acquire conditionally) class Set{ int size(){ // client and helper method } bool has(Element e){ // client method } } 18

  5. Objective 2: reentrant locks [APLAS’08] Reentrant locks are the main primitive to acquire/release locks in Java. They can be acquired more than once (and released accordingly) ë Convenient for programmers (no need to acquire conditionally) class Set{ int size(){ lock(this); ... unlock(this); return ...; } bool has(Element e){ lock(this); bool result; if(size()==0) unlock(this); return false; else ...; unlock(this); return ...; } } 19

  6. Objective 2: reentrant locks [APLAS’08] Reentrant locks are the main primitive to acquire/release locks in Java. They can be acquired more than once (and released accordingly) ë Convenient for programmers (no need to acquire conditionally) class Set{ int size(){ lock(this); ... unlock(this); return ...; } bool has(Element e){ lock(this); bool result; if(size()==0) unlock(this); return false; else ...; unlock(this); return ...; } } 20

  7. Objective 2: reentrant locks [APLAS’08] In separation logic [O’Hearn’07]: Each lock guards a part of the heap called the lock’s resource invariant. Resource invariants are exchanged between locks and threads: � When a lock is acquired, it lends its resource invariant to the acquiring thread. � When a lock is released, it claims back its resource invariant from the releasing thread. 21

  8. Objective 2: reentrant locks [APLAS’08] In separation logic [O’Hearn’07]: Each lock guards a part of the heap called the lock’s resource invariant. Resource invariants are exchanged between locks and threads: � When a lock is acquired, it lends its resource invariant to the acquiring thread. � When a lock is released, it claims back its resource invariant from the releasing thread. Resource invariants are represented by the distinguished abstract predicate inv : class Object{ pred inv = true; } 21

  9. ë Objective 2: reentrant locks [APLAS’08] In separation logic [O’Hearn’07]: Each lock guards a part of the heap called the lock’s resource invariant. Resource invariants are exchanged between locks and threads: � When a lock is acquired, it lends its resource invariant to the acquiring thread. � When a lock is released, it claims back its resource invariant from the releasing thread. 22

  10. Objective 2: reentrant locks [APLAS’08] In separation logic [O’Hearn’07]: Each lock guards a part of the heap called the lock’s resource invariant. Resource invariants are exchanged between locks and threads: � When a lock is acquired, it lends its resource invariant to the acquiring thread. � When a lock is released, it claims back its resource invariant from the releasing thread. But this is unsound for reentrant locks! ë We need to distinguish between initial acquirements and reentrant acquirements. 22

  11. Separation Logic for Reentrant Locks 4 formulas to speak about locks (where S is a multiset ): Lockset(S) ⑤ S contains x ⑤ x . fresh ⑤ x . initialized For each thread, we track the set of currently held locks: Lockset(S) : S is the multiset of currently held locks. S contains x : lockset S contains lock x . 23

  12. Separation Logic for Reentrant Locks 4 formulas to speak about locks (where S is a multiset ): Lockset(S) ⑤ S contains x ⑤ x . fresh ⑤ x . initialized For each thread, we track the set of currently held locks: Lockset(S) : S is the multiset of currently held locks. S contains x : lockset S contains lock x . For each lock, we track its abstract lock state: x . fresh : x ’s resource invariant is not initialized x . initialized : x ’s resource invariant is initialized. 23

  13. t ✉ ✩ t ✥ ✉ ë ë Initializing Locks C < ¯ π > ➔ : Γ ♣ x q (New) t true ✉ x ✏ new C < ¯ Γ ✩ π > t x . init * C classof x * � Γ ♣ u q➔ : Object x!=u * x . fresh ✉ ë After creation a lock cannot be acquired: x . initialized fails to match (Lock)’s precondition. 24

  14. Initializing Locks C < ¯ π > ➔ : Γ ♣ x q (New) t true ✉ x ✏ new C < ¯ Γ ✩ π > t x . init * C classof x * � Γ ♣ u q➔ : Object x!=u * x . fresh ✉ ë After creation a lock cannot be acquired: x . initialized fails to match (Lock)’s precondition. (Commit) t Lockset(S)*x . inv*x . fresh ✉ Γ ✩ x . commit t Lockset(S)* ✥ (S contains x)*x . initialized ✉ ë x . commit is a no-op. ë After being committed a lock can be acquired: (Commit)’s postcondition entails x . initialized . 24

  15. Acquiring Locks (Lock) t Lockset(S)*( ✥ S contains x)*x . initialized ✉ Γ ✩ lock ♣ x q t Lockset(x ☎ S)*x . inv ✉ ë First acquirement: resource invariants obtained. ë Nothing special to handle subclassing. (Re-Lock) Γ ✩ t Lockset(x ☎ S) ✉ lock ♣ x qt Lockset(x ☎ x ☎ S) ✉ ë Reentrant acquirement: x ’s resource invariant not obtained. 25

  16. Releasing Locks The 2 rules for releasing locks are dual to the rules for acquirement. ë Hence, we do not discuss them. 26

  17. ë Objectives 1 and 2: Achievements A sound verification system for realistic multithreaded Java programs. Usability tested against challenging case studies: � Concurrent iterator � Lock coupling algorithm (still some limitations) Algorithmic verification still to be developed 27

  18. Objectives 1 and 2: Achievements A sound verification system for realistic multithreaded Java programs. Usability tested against challenging case studies: � Concurrent iterator � Lock coupling algorithm (still some limitations) Algorithmic verification still to be developed After that: 3 new analyses based on separation logic ë 2 of these analyses are sketched in the next slides 27

  19. ë ✩ ✍ ë ✩ ✫ ë 1 st Analysis: Fast Disproving of Entailment [IWACO’09] Goal: Disprove entailment between separation logic formulas ë I.e. to prove A ✫ B 28

  20. ✩ ✫ ë 1 st Analysis: Fast Disproving of Entailment [IWACO’09] Goal: Disprove entailment between separation logic formulas ë I.e. to prove A ✫ B Usefulness: Program verifiers spend their time checking entailment. ë I.e. given the program’s state A , and the next command’s precondition B , ë program verifiers have to find a F such that A ✩ B ✍ F . 28

  21. 1 st Analysis: Fast Disproving of Entailment [IWACO’09] Goal: Disprove entailment between separation logic formulas ë I.e. to prove A ✫ B Usefulness: Program verifiers spend their time checking entailment. ë I.e. given the program’s state A , and the next command’s precondition B , ë program verifiers have to find a F such that A ✩ B ✍ F . In full separation logic, ✩ is undecidable. If we can prove that A ✫ B , then we know that F cannot be found. ë This avoids trying to prove unprovable programs. 28

  22. ♣❉ ⑤ ù ❫✥ ⑤ ù q ✫ ✫ Disproving Technique Soundness of the proof system: A ✩ B implies ♣❅ h , h ⑤ ù A Ñ h ⑤ ù B q 29

  23. Disproving Technique Soundness of the proof system: A ✩ B implies ♣❅ h , h ⑤ ù A Ñ h ⑤ ù B q Contraposition: ♣❉ h , h ⑤ ù A ❫✥ h ⑤ ù B q implies A ✫ B Goal of this work: Take A and B and prove that A ✫ B By discriminating models of A and B 29

  24. ❅ ⑤ ù ♣ q ↕ ♣ q ↕ ♣ q Disproving Technique (classical semantics) Objective: Find h such that h ⑤ ù A and ✥ h ⑤ ù B max(A) We compute bounds on the size of models. size(h) max : Formula Ñ Size min(A) min : Formula Ñ Size size : Model Ñ Size 30

  25. Disproving Technique (classical semantics) Objective: Find h such that h ⑤ ù A and ✥ h ⑤ ù B max(A) We compute bounds on the size of models. size(h) max : Formula Ñ Size min(A) min : Formula Ñ Size size : Model Ñ Size Properties of max and min (classical semantics): ❅ h , h ⑤ ù A implies min ♣ A q ↕ size ♣ h q ↕ max ♣ A q 30

  26. Disproving Technique (classical semantics) ♣❉ h , h ⑤ ù A ❫✥ h ⑤ ù B q implies A ✫ B ❅ h , h ⑤ ù A implies min ♣ A q ↕ size ♣ h q ↕ max ♣ A q Ó max ♣ A q ➔ min ♣ B q implies A ✫ B 31

  27. 1 st Analysis: Achievements A fast technique to disprove entailment. Two different trade offs between speed and precision 32

  28. 1 st Analysis: Achievements A fast technique to disprove entailment. Two different trade offs between speed and precision (two ways to define Size) 32

  29. 1 st Analysis: Achievements A fast technique to disprove entailment. Two different trade offs between speed and precision (two ways to define Size) Proven correct in Coq License-left proof scripts 32

  30. 2 nd Analysis: Optimizations by Proof Rewriting [SAS’09] We parallelize and optimize proven programs. To parallelize programs, you need to know: What data is accessed by programs. What data is not accessed by programs. 33

  31. 2 nd Analysis: Optimizations by Proof Rewriting [SAS’09] We parallelize and optimize proven programs. To parallelize programs, you need to know: What data is accessed by programs. What data is not accessed by programs. The good thing is: Separation logic proofs exhibit how data is accessed (or not): � Antiframes exhibit data that is accessed. (explained next) � The (Frame) rule exhibits data that is not accessed. (explained next) 33

  32. 2 nd Analysis: Optimizations by Proof Rewriting [SAS’09] We parallelize and optimize proven programs. To parallelize programs, you need to know: What data is accessed by programs. What data is not accessed by programs. The good thing is: Separation logic proofs exhibit how data is accessed (or not): � Antiframes exhibit data that is accessed. (explained next) � The (Frame) rule exhibits data that is not accessed. (explained next) Optimizations are expressed with a rewrite system between proof trees. Proof trees are derivations of Hoare triplets. 33

  33. program C High-Level Procedure program verifier C wrong C correct proof tree generator ( P is C ’s proof) C, P contributions proof tree rewriter ( C opt is C parallelized and optimized) C opt , P opt 34

  34. Separation Logic: (Frame) rule t Ξ a ✉ C t Ξ a ✶ ✉ (Frame Ξ f ) t Ξ a ✍ Ξ f ✉ C t Ξ a ✶ ✍ Ξ f ✉ C Ξ a Ξ a ′ Ξ f Ξ f Ξ a is the antiframe Ð accessed data Ξ f is the frame Ð not-accessed data Later, (Fr) sometimes abbreviates (Frame). 35

  35. With Frames: Parallelization Is Easy t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ t Ξ ✉ C t Θ ✉ (Fr Ξ ✶ ) (Fr Θ ) t Ξ ✍ Ξ ✶ ✉ C t Θ ✍ Ξ ✶ ✉ t Θ ✍ Ξ ✶ ✉ C ✶ t Θ ✍ Θ ✶ ✉ (Seq) t Ξ ✍ Ξ ✶ ✉ C ; C ✶ t Θ ✍ Θ ✶ ✉ Ó Parallelize t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ (Parallel) t Ξ ✉ C t Θ ✉ t Ξ ✍ Ξ ✶ ✉ C ⑥ C ✶ t Θ ✍ Θ ✶ ✉ 36

  36. Parallelize’s left hand side t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ t Ξ ✉ C t Θ ✉ (Fr Ξ ✶ ) (Fr Θ ) t Ξ ✍ Ξ ✶ ✉ C t Θ ✍ Ξ ✶ ✉ t Θ ✍ Ξ ✶ ✉ C ✶ t Θ ✍ Θ ✶ ✉ (Seq) t Ξ ✍ Ξ ✶ ✉ C ; C ✶ t Θ ✍ Θ ✶ ✉ Θ C Ξ Ξ ′ Ξ ′ 37

  37. Parallelize’s left hand side t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ t Ξ ✉ C t Θ ✉ (Fr Ξ ✶ ) (Fr Θ ) t Ξ ✍ Ξ ✶ ✉ C t Θ ✍ Ξ ✶ ✉ t Θ ✍ Ξ ✶ ✉ C ✶ t Θ ✍ Θ ✶ ✉ (Seq) t Ξ ✍ Ξ ✶ ✉ C ; C ✶ t Θ ✍ Θ ✶ ✉ Θ C Ξ Θ C ′ Θ ′ Ξ ′ Ξ ′ 37

  38. Parallelize’s right hand side t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ (Parallel) t Ξ ✉ C t Θ ✉ t Ξ ✍ Ξ ✶ ✉ C ⑥ C ✶ t Θ ✍ Θ ✶ ✉ C Ξ Θ C ′ Θ ′ Ξ ′ 38

  39. Parallelize Θ t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ C t Ξ ✉ C t Θ ✉ Ξ (Fr Ξ ✶ ) (Fr Θ ) Θ t Ξ ✍ Ξ ✶ ✉ C t Θ ✍ Ξ ✶ ✉ t Θ ✍ Ξ ✶ ✉ C ✶ t Θ ✍ Θ ✶ ✉ (Seq) C ′ Θ ′ t Ξ ✍ Ξ ✶ ✉ C ; C ✶ t Θ ✍ Θ ✶ ✉ Ξ ′ Ξ ′ Ó Parallelize Ó t Ξ ✶ ✉ C ✶ t Θ ✶ ✉ (Parallel) t Ξ ✉ C t Θ ✉ t Ξ ✍ Ξ ✶ ✉ C ⑥ C ✶ t Θ ✍ Θ ✶ ✉ C Ξ Θ C ′ Θ ′ Ξ ′ 39

  40. 2 nd Analysis: Achievements An entirely new technique to parallelize and optimize programs. ë Other optimizations than parallelization have been studied. No ad-hoc analyses: separation logic proofs are taken as analyses. Can parallelize any code (i.e. not focused on loops). Soundness is easier to prove than for classical approaches. License-left prototype implementation. 40

  41. Related Work Program verification: Separation logic for sequential Java [Parkinson’05,Distefano et al.’08,Chin et al.’08] Separation logic for multithreaded C [Gotsman et al.’07,Appel et al.’07] Boogie for multithreaded C# [Barnett et al.’04,Jacobs et al.’06] ESC/Java2 for Java [Leino et al.’02,Kiniry et al.’04] 41

  42. Related Work Program verification: Separation logic for sequential Java [Parkinson’05,Distefano et al.’08,Chin et al.’08] Separation logic for multithreaded C [Gotsman et al.’07,Appel et al.’07] Boogie for multithreaded C# [Barnett et al.’04,Jacobs et al.’06] ESC/Java2 for Java [Leino et al.’02,Kiniry et al.’04] Algorithms for entailment/disproving: Sound and complete entailment in Smallfoot [Berdine et al.’04] Sound entailment in JStar [Parkinson et al.’08] Sound and complete entailment and refutation [Galmiche et al.’08] 41

  43. Related Work Program verification: Separation logic for sequential Java [Parkinson’05,Distefano et al.’08,Chin et al.’08] Separation logic for multithreaded C [Gotsman et al.’07,Appel et al.’07] Boogie for multithreaded C# [Barnett et al.’04,Jacobs et al.’06] ESC/Java2 for Java [Leino et al.’02,Kiniry et al.’04] Algorithms for entailment/disproving: Sound and complete entailment in Smallfoot [Berdine et al.’04] Sound entailment in JStar [Parkinson et al.’08] Sound and complete entailment and refutation [Galmiche et al.’08] Automatic parallelization: Many “classical” approaches By using separation logic [Raza et al.’09] 41

  44. Main Publications Separation Logic Contracts for a Java-like Language with Fork/Join; Haack and Hurlin; AMAST’08 � Reasoning about Java’s Reentrant Locks; Haack, Huisman, and Hurlin; APLAS’08 � Specifying and Checking Protocols of Multithreaded Classes; Hurlin; SAC’09 Resource Usage Protocols for Iterators; Haack and Hurlin; Journal of Object Technology’09 � Size Does Matter: Two Certified Abstractions to Disprove Entailment in Intuitionistic and Classical Separation Logic; Hurlin, Bobot, and Summers; IWACO’09 � Automatic Parallelization and Optimization of Programs by Proof Rewriting; Hurlin; SAS’09 42

  45. Main Publications Separation Logic Contracts for a Java-like Language with Fork/Join; Haack and Hurlin; AMAST’08 � Reasoning about Java’s Reentrant Locks; Haack, Huisman, and Hurlin; APLAS’08 � Specifying and Checking Protocols of Multithreaded Classes; Hurlin; SAC’09 Resource Usage Protocols for Iterators; Haack and Hurlin; Journal of Object Technology’09 � Size Does Matter: Two Certified Abstractions to Disprove Entailment in Intuitionistic and Classical Separation Logic; Hurlin, Bobot, and Summers; IWACO’09 � Automatic Parallelization and Optimization of Programs by Proof Rewriting; Hurlin; SAS’09 Developments: 1 Some Coq proofs for the AMAST and APLAS papers. 2 ocaml implementation of some of the techniques described in the SAC paper. 3 Full Coq proofs for the IWACO paper. 4 ocaml and Java+tom prototype implementation of the SAS paper. 42

  46. ë ë Conclusion First, we developed: A sound verification system for multithreaded Java programs in separation logic, 43

  47. ë Conclusion First, we developed: A sound verification system for multithreaded Java programs in separation logic, ë that uses realistic primitives, 43

  48. Conclusion First, we developed: A sound verification system for multithreaded Java programs in separation logic, ë that uses realistic primitives, ë and that handles challenging examples (iterator, lock-coupling). 43

  49. Conclusion First, we developed: A sound verification system for multithreaded Java programs in separation logic, ë that uses realistic primitives, ë and that handles challenging examples (iterator, lock-coupling). Second: We extended previous work on protocols. (omitted in this talk) We discovered a fast algorithm to disprove entailment. We showed how to parallelize and optimize programs by rewriting their proofs. 43

  50. Future Work For the verification system: Implementing it! Doing a large case study For the disproving algorithm: Extension to object-orientation ë By keeping its simplicity and its usefulness (not straightforward) For the parallelizing analysis: Extension to object-oriented programs (easy) Extension to loops Ñ to battle it out with classical parallelizers! 44

  51. Thank you

  52. Fork and join in terms of resources (2) thread t 0 46

  53. Fork and join in terms of resources (2) thread t 0 t 1 .fork() thread t 1 46

  54. Fork and join in terms of resources (2) thread t 0 t 1 .fork() thread t 1 46

  55. Fork and join in terms of resources (2) thread t 0 t 1 .fork() t 2 .start() thread t 1 thread t 2 46

  56. Releasing Locks (Re-Unlock) Γ ✩ t Lockset(x ☎ x ☎ S) ✉ unlock ♣ x qt Lockset(x ☎ S) ✉ ë Releasing x but x ’s reentrancy level → 1: invariant not abandoned. (Unlock) Γ ✩ t Lockset(x ☎ S)* x . inv ✉ unlock ♣ x qt Lockset(S) ✉ ë x ’s reentrancy level not known to be → 1, x ’s resource invariant abandoned. 47

  57. Disproving Technique (classical semantics) ♣❉ h , h ⑤ ù A ❫✥ h ⑤ ù B q implies A ✫ B ❅ h , h ⑤ ù A implies min ♣ A q ↕ size ♣ h q ↕ max ♣ A q Ó max ♣ A q ➔ min ♣ B q implies A ✫ B 48

  58. ✶ ✁ q ✷ ♣ q ♣ ♣ q rs ë ✶ ✁ q ✶ � ✷ ✷ ♣♣ q ♣ ♣ q rsq ✏ � Defining size ∆ size ♣ h q ✏ sum of h ’s permissions size : Model Ñ Perm 49

  59. Defining size ∆ size ♣ h q ✏ sum of h ’s permissions size : Model Ñ Perm Models h are lists of triples of an address, a permission, and a value. ë An example model is ♣ 42 , π , 3 q :: ♣ 47 , π ✶ , ✁ 5 q :: ♣ 42 , π ✷ , 0 q :: rs . size ♣♣ 42 , π , 3 q :: ♣ 47 , π ✶ , ✁ 5 q :: ♣ 42 , π ✷ , 0 q :: rsq ✏ π � π ✶ � π ✷ 49

  60. Defining max / min (classical semantics)(excerpt) π π max ♣ ÞÑ q✏ π min ♣ ÞÑ q✏ π max ♣ A ✍ B q ✏ max ♣ A q� π max ♣ B q min ♣ A ✍ B q ✏ min ♣ A q� π min ♣ B q ù a π h ⑤ ÞÑ v h ✏ ♣ a , π , v q iff h ⑤ ù A ✍ B ❉ h A , h B , h ✏ h A ❩ h B , h A ⑤ ù A and h B ⑤ ù B iff 50

  61. Defining max / min (classical semantics)(excerpt) max ♣ A ❫ B q✏ min π ♣ max ♣ A q , max ♣ B qq min ♣ A ❫ B q✏ max π ♣ min ♣ A q , min ♣ B qq max ♣ A ❴ B q✏ max π ♣ max ♣ A q , max ♣ B qq min ♣ A ❴ B q✏ min π ♣ min ♣ A q , min ♣ B qq h ⑤ ù A ❫ B h ⑤ ù A and h ⑤ ù B iff h ⑤ ù A ❴ B h ⑤ ù A or h ⑤ ù B iff 51

  62. Defining max / min (classical semantics)(excerpt) π π max ♣ ÞÑ q✏ π min ♣ ÞÑ q✏ π max ♣ A ✍ B q ✏ max ♣ A q� π max ♣ B q min ♣ A ✍ B q ✏ min ♣ A q� π min ♣ B q ù a π h ⑤ ÞÑ v iff h ✏ ♣ a , π , v q h ⑤ ù A ✍ B iff ❉ h A , h B , h ✏ h A ❩ h B , h A ⑤ ù A and h B ⑤ ù B max(A) max(B) size(A) size(B) 52

  63. ♣ q Defining max / min (classical semantics)(excerpt) π π max ♣ ÞÑ q✏ π min ♣ ÞÑ q✏ π max ♣ A ✍ B q ✏ max ♣ A q� π max ♣ B q min ♣ A ✍ B q ✏ min ♣ A q� π min ♣ B q ù a π h ⑤ ÞÑ v iff h ✏ ♣ a , π , v q h ⑤ ù A ✍ B iff ❉ h A , h B , h ✏ h A ❩ h B , h A ⑤ ù A and h B ⑤ ù B max(A) max(B) size(A) size(B) 53

  64. Defining max / min (classical semantics)(excerpt) π π max ♣ ÞÑ q✏ π min ♣ ÞÑ q✏ π max ♣ A ✍ B q ✏ max ♣ A q� π max ♣ B q min ♣ A ✍ B q ✏ min ♣ A q� π min ♣ B q ù a π h ⑤ ÞÑ v iff h ✏ ♣ a , π , v q h ⑤ ù A ✍ B iff ❉ h A , h B , h ✏ h A ❩ h B , h A ⑤ ù A and h B ⑤ ù B max(A) max(B) size(A) size(B) 53

  65. Defining max / min (classical semantics)(excerpt) π π max ♣ ÞÑ q✏ π min ♣ ÞÑ q✏ π max ♣ A ✍ B q ✏ max ♣ A q� π max ♣ B q min ♣ A ✍ B q ✏ min ♣ A q� π min ♣ B q ù a π h ⑤ ÞÑ v iff h ✏ ♣ a , π , v q h ⑤ ù A ✍ B iff ❉ h A , h B , h ✏ h A ❩ h B , h A ⑤ ù A and h B ⑤ ù B max(A ⋆ B) 54

Recommend


More recommend