- The document discusses global protocol combinators for specifying multiparty session types in OCaml.
- It presents an approach to ensure deadlock-freedom solely through type checking in OCaml, without code generation. Local types are inferred from the global protocol specification.
- Well-formedness of the global protocol and type checking of the OCaml program ensure deadlock-freedom. Branching and non-determinism in protocols can be detected as type errors.
情報システム障害解析のための知識グラフ構築の試み / Constructing a knowledge graph for information sys...Shinji Takao
人工知能学会 第25回知識流通ネットワーク研究会発表 http://sigksn.html.xdomain.jp/conf25/index.html
システム障害解析に関する専門家知識の抽出、グラフ化、DB化を行った際得られた知見と、知識流通手段としての知識グラフの可能性と課題を考察した結果を報告します。
Knowledge graphs have been getting attention because of its relevance to interpretable AI. Not only that, they also can be useful as a knowledge sharing mean which enable non-experts to utilize experts’ knowledge. We aim to report findings from constructing a knowledge graph through eliciting experts’ knowledge and building a knowledge database. We also suggest the possibilities and issues of knowledge graph as a knowledge sharing mean.
This document contains notes from a machine learning discussion. It includes:
1. An introduction to BakFoo Inc. CEO Yuta Kashino's background in astrophysics, Python, and realtime data platforms.
2. References to papers and researchers in Bayesian deep learning and probabilistic programming, including Edward library creators Dustin Tran and Blei Lab.
3. An overview of how Edward combines TensorFlow for deep learning with probabilistic programming to perform Bayesian modeling, inference via VI and MCMC, and criticisms.
The document discusses control as inference in Markov decision processes (MDPs) and partially observable MDPs (POMDPs). It introduces optimality variables that represent whether a state-action pair is optimal or not. It formulates the optimal action-value function Q* and optimal value function V* in terms of these optimality variables and the reward and transition distributions. Q* is defined as the log probability of a state-action pair being optimal, and V* is defined as the log probability of a state being optimal. Bellman equations are derived relating Q* and V* to the reward and next state value.
1. The document discusses energy-based models (EBMs) and how they can be applied to classifiers. It introduces noise contrastive estimation and flow contrastive estimation as methods to train EBMs.
2. One paper presented trains energy-based models using flow contrastive estimation by passing data through a flow-based generator. This allows implicit modeling with EBMs.
3. Another paper argues that classifiers can be viewed as joint energy-based models over inputs and outputs, and should be treated as such. It introduces a method to train classifiers as EBMs using contrastive divergence.
The document discusses Open-DO, an open source initiative for developing safety-critical software. It provides an overview of Open-DO concepts like FLOSS, agile development practices, and high-integrity certification. Updates on Open-DO include new community projects, conferences, and tools to support qualifications. Formal methods like Couverture and Hi-Lite are presented as ways to verify properties and generate verification conditions for proof.
Bounded Model Checking for C Programs in an Enterprise EnvironmentAdaCore
This document discusses using bounded model checking to analyze C programs at scale in an enterprise environment. It describes compiling thousands of software packages using a tool called goto-cc that converts C code to an intermediate representation. This allows running verification tools to find bugs. Many bugs were found and reported, improving quality. The goal is to focus on developing verification methods and analyzing a large codebase to find more bugs and security issues.
情報システム障害解析のための知識グラフ構築の試み / Constructing a knowledge graph for information sys...Shinji Takao
人工知能学会 第25回知識流通ネットワーク研究会発表 http://sigksn.html.xdomain.jp/conf25/index.html
システム障害解析に関する専門家知識の抽出、グラフ化、DB化を行った際得られた知見と、知識流通手段としての知識グラフの可能性と課題を考察した結果を報告します。
Knowledge graphs have been getting attention because of its relevance to interpretable AI. Not only that, they also can be useful as a knowledge sharing mean which enable non-experts to utilize experts’ knowledge. We aim to report findings from constructing a knowledge graph through eliciting experts’ knowledge and building a knowledge database. We also suggest the possibilities and issues of knowledge graph as a knowledge sharing mean.
This document contains notes from a machine learning discussion. It includes:
1. An introduction to BakFoo Inc. CEO Yuta Kashino's background in astrophysics, Python, and realtime data platforms.
2. References to papers and researchers in Bayesian deep learning and probabilistic programming, including Edward library creators Dustin Tran and Blei Lab.
3. An overview of how Edward combines TensorFlow for deep learning with probabilistic programming to perform Bayesian modeling, inference via VI and MCMC, and criticisms.
The document discusses control as inference in Markov decision processes (MDPs) and partially observable MDPs (POMDPs). It introduces optimality variables that represent whether a state-action pair is optimal or not. It formulates the optimal action-value function Q* and optimal value function V* in terms of these optimality variables and the reward and transition distributions. Q* is defined as the log probability of a state-action pair being optimal, and V* is defined as the log probability of a state being optimal. Bellman equations are derived relating Q* and V* to the reward and next state value.
1. The document discusses energy-based models (EBMs) and how they can be applied to classifiers. It introduces noise contrastive estimation and flow contrastive estimation as methods to train EBMs.
2. One paper presented trains energy-based models using flow contrastive estimation by passing data through a flow-based generator. This allows implicit modeling with EBMs.
3. Another paper argues that classifiers can be viewed as joint energy-based models over inputs and outputs, and should be treated as such. It introduces a method to train classifiers as EBMs using contrastive divergence.
The document discusses Open-DO, an open source initiative for developing safety-critical software. It provides an overview of Open-DO concepts like FLOSS, agile development practices, and high-integrity certification. Updates on Open-DO include new community projects, conferences, and tools to support qualifications. Formal methods like Couverture and Hi-Lite are presented as ways to verify properties and generate verification conditions for proof.
Bounded Model Checking for C Programs in an Enterprise EnvironmentAdaCore
This document discusses using bounded model checking to analyze C programs at scale in an enterprise environment. It describes compiling thousands of software packages using a tool called goto-cc that converts C code to an intermediate representation. This allows running verification tools to find bugs. Many bugs were found and reported, improving quality. The goal is to focus on developing verification methods and analyzing a large codebase to find more bugs and security issues.
The prevalent wisdom seems to be that FSharp is only for Math, Science and Engineering. F# for Boring Line of Business Apps aims to show why it's capable of far more than that.
This document discusses the padding oracle attack, which allows decryption of encrypted data by exploiting flaws in padding validation on encrypted ciphertext. It describes how the attack works by using a padding validation "oracle" to decrypt ciphertext blocks one-by-one. It then explains how this can be used to decrypt web traffic and authentication cookies, potentially allowing complete compromise of the system.
Keynote (Mike Muller) - Is There Anything New in Heterogeneous Computing - by...AMD Developer Central
Keynote presentation, Is There Anything New in Heterogeneous Computing, by Mike Muller, Chief Technology Officer, ARM, at the AMD Developer Summit (APU13), Nov. 11-13, 2013.
cReComp is an automated design tool that improves the productivity of developing ROS-compliant FPGA components. It generates a component-oriented interface that enables communication between FPGA hardware and ROS software. By describing a user logic circuit and configuration in simple files, cReComp can create the hardware interface circuit, ROS application code, and ROS message files to build a complete ROS-compliant FPGA component in less than an hour, significantly improving development time and productivity over manual design. An evaluation experiment showed that cReComp reduced the time and lines of code required for componentization compared to manual development.
HIS 2017 Mark Batty-Industrial concurrency specification for C/C++jamieayre
Modern computer systems have intricate memory hierarchies that violate the intuition of a global timeline of interleaved memory accesses. In these so-called relaxed-memory systems, it can be dangerous to use intuition, specifications are universally unreliable, and the outcome of testing is both wildly nondeterministic and dependent on hardware that is getting more permissive of odd behaviour with each generation. These complications pervade the whole system, and have led to bugs in language specifications, deployed processors, compilers, and vendor-endorsed programming idioms – it is clear that current engineering practice is severely lacking.
I will describe my part of a sustained effort in the academic community to tackle these problems by applying a range of techniques, from exhaustive testing to mechanised formal specification and proof. I will focus on a vein of work with strong industrial impact: the formalisation, refinement and validation of the 2011/14/17 C and C++ concurrency design, leading to changes in the ratified international standard, and ultimately uncovering fundamental flaws that lead us to the state of the art in concurrent language specification. This work represents an essential enabling step for verification on modern concurrent systems
C is a general purpose programming language that is like a sea - its depths cannot fully be explored even after years of practice. The document discusses the history of C and other programming languages it evolved from like B, highlights C's importance and flexibility. It also covers basic C programming concepts like data types, operators, statements and functions. The last few sections describe structures, unions, pointers and how to write and execute a simple C program.
The document provides instructions and programs for a VLSI lab. It outlines the steps to compile and simulate Verilog codes using Cadence tools. It then lists 10 programs that involve writing Verilog code and test benches for basic digital logic gates and circuits like inverters, buffers, transmission gates. It also provides programs for designing analog circuits like differential amplifiers and op-amps by completing the full design flow from schematic to layout extraction.
Traitement temps réel chez Streamroot - Golang Paris Juin 2016Simon Caplette
This document summarizes Simon Caplette's work as a Backend Scalability Engineer at streamroot.io, which provides peer-to-peer functionality to save large video broadcasters bandwidth. Key aspects of Streamroot's realtime systems built with Go include high concurrency and scalability components like trackers, signaling servers, and autoscalers. Go was well-suited due to its built-in concurrency and ability to handle many concurrent processes. The document also discusses Streamroot's realtime data pipeline using Kafka and InfluxDB for low latency analytics.
Go (often referred to as “Golang”) is a fairly new programming language, version 1.0 released in 2012. Its three creators include Ken Thompson, who is the legendary father of UNIX and the inventor of the C language. The motives behind Go are very similar to those behind Java’s origins: much easier to use than C/C++, automatic garbage collection, no pointer arithmetic, built-in concurrency support, rich standard library, strong networking support.
(Open) MPI, Parallel Computing, Life, the Universe, and EverythingJeff Squyres
This talk is a general discussion of the current state of Open MPI, and a deep dive on two new features:
1. The flexible process affinity system (I presented many of these slides at the Madrid EuroMPI'13 conference in September 2013).
2. The MPI-3 "MPI_T" tools interface.
I originally gave this talk at Lawrence Berkeley Labs on Thursday, November 7, 2013.
The Onward Journey: Porting Twisted to Python 3Craig Rodrigues
This document discusses porting the Twisted Python library to Python 3. It describes Twisted as a networking library that uses asynchronous programming. The author ported over 325 pull requests to help move Twisted to Python 3. Some challenges included changes to Python 3 like print becoming a function and str handling, as well as porting old C extensions. Running extensive unit tests was important. While difficult, porting benefits code quality and keeps Twisted compatible with Python's direction.
Go is an exciting new programming language developed at Google that focuses on high performance and easing the developer experience. It has many advantages over other languages like C++ such as having a simple, quick to learn syntax, extremely fast compiler and execution speeds, powerful standard library, easy concurrency with goroutines and channels, and implicit interfaces. While still missing some features like a full IDE, Go shows great promise for building scalable server side applications and performing data processing.
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...Flink Forward
Python is popular amongst data scientists and engineers for data processing tasks. The big data ecosystem has traditionally been rather JVM centric. Often Java (or Scala) are the only viable option to implement data processing pipelines. That sometimes poses an adoption barrier for organizations that have already invested in other language ecosystems. The Apache Beam project provides a unified programming model for data processing and its ongoing portability effort aims to enable multiple language SDKs (currently Java, Python and Go) on a common set of runners. The combination of Python streaming on the Apache Flink runner is one example. Let’s take a look how the Flink runner translates the Beam model into the native DataStream (or DataSet) API, how the runner is changing to support portable pipelines, how Python user code execution is coordinated with gRPC based services and how a sample pipeline runs on Flink.
Mario Molina, Datio, Software Engineer
Kafka Streams is an open source JVM library for building event streaming applications on top of Apache Kafka. Its goal is to allow programmers to create efficient, real-time, streaming applications and perform analysis and operations on the incoming data.
In this presentation we’ll cover the main features of Kafka Streams and do a live demo!
This demo will be partially on Confluent Cloud, if you haven’t already signed up, you can try Confluent Cloud for free. Get $200 every month for your first three months ($600 free usage in total) get more information and claim it here: https://cnfl.io/cloud-meetup-free
https://www.meetup.com/Mexico-Kafka/events/271972045/
Structure-Compiler-phases information about basics of compiler. Pdfpdfovidlivi91
A compiler is a program that translates source code written in one programming language into another language. It performs two main tasks: analysis of the source program and synthesis of a machine-language program. The structure of a compiler typically includes a scanner, parser, semantic routines, code generator, and optimizer. The scanner reads the source code and groups characters into tokens. The parser checks the syntax against a grammar. Semantic routines perform static checking and translation. The code generator produces target code, which may then be optimized. An example compiler output is shown translating a sample program into assembly code.
Portable and reproducible bioinformatic analysis. Neoantigen discovery.Vladimir Kovacevic
Introduction to genome sequencing and bioinformatics. Constructing and execution portable, reproducible analysis in Common Workflow Language. Jupyter Notebook on the cloud. Example of bioinformatics analysis: Neoantigen discovery using NGS data.
Similar to OCaml-MPST / Global Protocol Combinators (20)
Flutter is a popular open source, cross-platform framework developed by Google. In this webinar we'll explore Flutter and its architecture, delve into the Flutter Embedder and Flutter’s Dart language, discover how to leverage Flutter for embedded device development, learn about Automotive Grade Linux (AGL) and its consortium and understand the rationale behind AGL's choice of Flutter for next-gen IVI systems. Don’t miss this opportunity to discover whether Flutter is right for your project.
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemPeter Muessig
Learn about the latest innovations in and around OpenUI5/SAPUI5: UI5 Tooling, UI5 linter, UI5 Web Components, Web Components Integration, UI5 2.x, UI5 GenAI.
Recording:
https://www.youtube.com/live/MSdGLG2zLy8?si=INxBHTqkwHhxV5Ta&t=0
Artificia Intellicence and XPath Extension FunctionsOctavian Nadolu
The purpose of this presentation is to provide an overview of how you can use AI from XSLT, XQuery, Schematron, or XML Refactoring operations, the potential benefits of using AI, and some of the challenges we face.
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfVALiNTRY360
Salesforce Healthcare CRM, implemented by VALiNTRY360, revolutionizes patient management by enhancing patient engagement, streamlining administrative processes, and improving care coordination. Its advanced analytics, robust security, and seamless integration with telehealth services ensure that healthcare providers can deliver personalized, efficient, and secure patient care. By automating routine tasks and providing actionable insights, Salesforce Healthcare CRM enables healthcare providers to focus on delivering high-quality care, leading to better patient outcomes and higher satisfaction. VALiNTRY360's expertise ensures a tailored solution that meets the unique needs of any healthcare practice, from small clinics to large hospital systems.
For more info visit us https://valintry360.com/solutions/health-life-sciences
UI5con 2024 - Bring Your Own Design SystemPeter Muessig
How do you combine the OpenUI5/SAPUI5 programming model with a design system that makes its controls available as Web Components? Since OpenUI5/SAPUI5 1.120, the framework supports the integration of any Web Components. This makes it possible, for example, to natively embed own Web Components of your design system which are created with Stencil. The integration embeds the Web Components in a way that they can be used naturally in XMLViews, like with standard UI5 controls, and can be bound with data binding. Learn how you can also make use of the Web Components base class in OpenUI5/SAPUI5 to also integrate your Web Components and get inspired by the solution to generate a custom UI5 library providing the Web Components control wrappers for the native ones.
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesQuickdice ERP
Explore the seamless transition to e-invoicing with this comprehensive guide tailored for Saudi Arabian businesses. Navigate the process effortlessly with step-by-step instructions designed to streamline implementation and enhance efficiency.
Mobile app Development Services | Drona InfotechDrona Infotech
Drona Infotech is one of the Best Mobile App Development Company In Noida Maintenance and ongoing support. mobile app development Services can help you maintain and support your app after it has been launched. This includes fixing bugs, adding new features, and keeping your app up-to-date with the latest
Visit Us For :
Transform Your Communication with Cloud-Based IVR SolutionsTheSMSPoint
Discover the power of Cloud-Based IVR Solutions to streamline communication processes. Embrace scalability and cost-efficiency while enhancing customer experiences with features like automated call routing and voice recognition. Accessible from anywhere, these solutions integrate seamlessly with existing systems, providing real-time analytics for continuous improvement. Revolutionize your communication strategy today with Cloud-Based IVR Solutions. Learn more at: https://thesmspoint.com/channel/cloud-telephony
SMS API Integration in Saudi Arabia| Best SMS API ServiceYara Milbes
Discover the benefits and implementation of SMS API integration in the UAE and Middle East. This comprehensive guide covers the importance of SMS messaging APIs, the advantages of bulk SMS APIs, and real-world case studies. Learn how CEQUENS, a leader in communication solutions, can help your business enhance customer engagement and streamline operations with innovative CPaaS, reliable SMS APIs, and omnichannel solutions, including WhatsApp Business. Perfect for businesses seeking to optimize their communication strategies in the digital age.
Unveiling the Advantages of Agile Software Development.pdfbrainerhub1
Learn about Agile Software Development's advantages. Simplify your workflow to spur quicker innovation. Jump right in! We have also discussed the advantages.
1. Keigo Imai1
(with Rumyana Neykova2, Nobuko Yoshida3 and Shoji Yuen4)
1Gifu University (JP) 2Brunel University London (UK)
3Imperial College London (UK) 4Nagoya University (JP)
PLAS Group Seminar, University of Kent
16th Sept. 2019
1
Global Protocol Combinators:
Static Structural Multiparty Sessions Over
Simply Typed Channels
in OCaml
3. Deadlocks in message-passing concurrency: Protocols prevent them!
3
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
4. Deadlocks in message-passing concurrency: Protocols prevent them!
4
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
C
wrong usage (direction)…
② input① output
order matters…
5. Deadlocks in message-passing concurrency: Protocols prevent them!
5
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
A B C
Communication protocol!
C
wrong usage (direction)…
② input① output
order matters…
6. Deadlocks in message-passing concurrency: Protocols prevent them!
6
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
A B C
Communication protocol!
C
wrong usage (direction)…
② input① output
order matters…
Best practice:
1. Design a communication protocol and check it
2. Focus on its local behaviours
3. Enforce protocol in the program code
7. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
7
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
[Honda et al., 2008]
8. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
8
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
[Honda et al., 2008]
9. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
9
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
[Honda et al., 2008]
10. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
10
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
[Honda et al., 2008]
11. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
11
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
deadlock-free!
[Honda et al., 2008]
12. deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
12
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
deadlock-free!
[Honda et al., 2008]
How to implement MPSTs
in a programming language?
Question
13. ③ LC ⊢ PC ?
Go
Thread
State of the art: Deadlock freedom via code generation
13
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
14. ③ LC ⊢ PC ?
Go
Thread
State of the art: Deadlock freedom via code generation
14
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
15. ③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
15
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
16. ③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
16
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
deadlock-free
17. ③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
17
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
deadlock-free
Is it possible to implement MPSTs
without code generation?
Question
18. ③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
18
Yes (!) How?
19. ↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
19
Yes (!) How?
20. ↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
20
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!) How?
21. ↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
21
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!) How?
22. ↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
22
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!)
deadlock-free!
How?
23. ↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
23
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!)
deadlock-free!
How?
How/why do they work??
24. Global Combinators and well-formedness check
24
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
25. Global Combinators and well-formedness check
25
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
26. Global Combinators and well-formedness check
26
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
27. Global Combinators and well-formedness check
27
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
Example: Adding a branch to Simple OAuth protocol
(a few plumbings needed to convince the type checker)
Each branch must begin from s
28. Global Combinators and well-formedness check
28
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
29. Global Combinators and well-formedness check
29
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
Non-determinism/
Deadlock
in a protocol
a
30. Global Combinators and well-formedness check
30
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
… is reported as a type error
Non-determinism/
Deadlock
in a protocol
a
31. (Deadlock and type errors: An analysis)
31
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s
c's first action is output to a
32. Deriving local types via type inference
OCaml infers Local Types from global combinators.
32
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
33. Deriving local types via type inference
OCaml infers Local Types from global combinators.
33
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
34. Deriving local types via type inference
OCaml infers Local Types from global combinators.
34
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Destination role's names are a method of an object
< role_S
< role_A
< role_A
35. Deriving local types via type inference
OCaml infers Local Types from global combinators.
35
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Output labels are methods in an object
< password
Destination role's names are a method of an object
< role_S
< role_A
< role_A
36. Deriving local types via type inference
OCaml infers Local Types from global combinators.
36
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Input labels are (polymorphic) variant type tags
[ `login
[ `auth
Output labels are methods in an object
< password
Destination role's names are a method of an object
< role_S
< role_A
< role_A
37. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
37
③ LC ⊢ PC ✔
38. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
38
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
39. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
39
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
40. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
40
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
41. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
41
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
42. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
42
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
43. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
43
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
role_A
< role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
44. let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
44
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
`auth
[ `auth
role_A
< role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
45. let ch = get_ch s oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
45
Protocol conformance via OCaml's type checking③ LC ⊢ PC ✔
ro
If there is a
typo …
OCaml reports a type error at this point
46. ↓ A single OCaml Source code file (.ml)
OCaml
Program
OCaml
Program
OCaml
Program
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom by Types!
46
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking
& inference
Recap
deadlock-free!
47. ↓ A single OCaml Source code file (.ml)
OCaml
Program
OCaml
Program
OCaml
Program
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom by Types!
47
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking
& inference
Recap
deadlock-free!
Are they really correct??
48. GPC: Are they correct
48
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC with Deadlock-freedom Theorem
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
49. GPC: Are they correct
49
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC with Deadlock-freedom Theorem
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
51. A. Key idea: Global Combinators pre-generate channels
51
S
C A
⟨⟩ ⟨⟩
⟨⟩
let oAuth = finish
52. A. Key idea: Global Combinators pre-generate channels
52
S
C A
Sauth
⟨?Sauth⟩ ⟨!Sauth⟩
⟨⟩
let oAuth = (A → C) auth finish
53. A. Key idea: Global Combinators pre-generate channels
53
let oAuth = (C → A) password ((A → C) auth finish)
S
C A
Sauth
Spasswd
⟨!Spasswd; ?Sauth⟩ ⟨?Spasswd; !Sauth⟩
⟨⟩
54. A. Key idea: Global Combinators pre-generate channels
54
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨!Slogin ⟩
55. A. Key idea: Global Combinators pre-generate channels
55
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨!Slogin ⟩
56. Distribute them and start the communication
56
PS
PC
PA
!Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
57. Distribute them and start the communication
57
PS
PC
PA
0| !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
58. Distribute them and start the communication
58
PS
PC
PA
0| ?Sauth.0| !Sauth.0
60. Distribute them and start the communication
60
PS
PC
PA
!Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
❖ All these channels are simply-typed (hence no type-errors)
❖ Global combinators aim to be deadlock-free
❖ The nested structure enforces usage order
Point
61. GPC: Are they correct? (cont.)
61
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC (with Deadlock-freedom Theorem)
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators (with hints to OCaml DSL)
❖ Session Type merging
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
62. B. OCamlM: Formalisation of GPC with Deadlock-freedom Theorem
• A minimal concurrent language with structural subtyping,
equi-recursive types and simply-typed channels
• Typing rules for global combinators
62
63. Typing rules
63
p1 pn
… … …
Point: give an index for each role (and order roles)
wf(G) ✔, G↾C
64. The typing rule for (-->)
64
p1 pn
…
pi pj
… …
wf(G) ✔, G↾C
i
65. The typing rule for (-->)
65
p1 pn
…
pi pj
… …
Index-based type update
wf(G) ✔, G↾C
i
66. The typing rule for (-->)
66
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
wf(G) ✔, G↾C
i
67. The typing rule for (-->)
67
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
Implement them by using GADTs and
polymorphic lens (explained later)
available in OCaml
wf(G) ✔, G↾C
i
68. The typing rule for (-->)
68
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
Requires first-class record fields
(methods) and variant tags
⇒ Encode them as values
encode it in OCaml
Implement them by using GADTs and
polymorphic lens (explained later)
available in OCaml
wf(G) ✔, G↾C
i
70. The typing rule for branching (choice_at)
70
Ensure that pa is a sending
wf(G) ✔, G↾C
71. The typing rule for branching (choice_at)
71
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
wf(G) ✔, G↾C
72. The typing rule for branching (choice_at)
72
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
Merge two records (objects) into one
wf(G) ✔, G↾C
73. The typing rule for branching (choice_at)
73
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
Merge two records (objects) into one
Encode disjoint record merging
encode it in OCaml
wf(G) ✔, G↾C
74. The typing rule for branching (choice_at)
74
wf(G) ✔, G↾C
Too restrictive for communication protocols
Solution: Subtyping!
Requires each role having the same type (behaviour) in each branch
→ seems standard wrt. if-then-else construct, but
75. The typing rule for branching (choice_at)
75
wf(G) ✔, G↾C
Too restrictive for communication protocols
Solution: Subtyping!
Row polymorphism
(objects and polymorphic variants)
available in OCaml
Requires each role having the same type (behaviour) in each branch
→ seems standard wrt. if-then-else construct, but
76. Typing rules
76
…
p1 pn
…
pi
…
p1 pn
…
pi
…
p1 pn
…
pi
…
Γ ⊢ choice … {g1; g2} : ⋯×p&{m1:T1, m2:T2}×⋯
Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g2 : ⋯×p&{m2:T2}×⋯
Desired type
(According to Full Merging in MPST)
A problem:
p&{m1:T1} ≠ p&{m2:T2}
79. Deadlock and type errors: An analysis
79
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
80. Deadlock and type errors: An analysis
80
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is output to a <a: <quit: !bool*cont2>>
81. Deadlock and type errors: An analysis
81
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s <s: ?[login_str*cont1]>
c's first action is output to a <a: <quit: !bool*cont2>>
82. Deadlock and type errors: An analysis
82
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s <s: ?[login_str*cont1]>
c's first action is output to a <a: <quit: !bool*cont2>>
No least upper bound (common supertype)
⇒ type error
No least upper bound (common supertype)
⇒ type error
83. A note on typing
83
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
Making a multiplexed channel from
simply-typed channels
84. A note on typing
84
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
85. A note on typing
85
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
86. A note on typing
86
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
87. A note on typing
87
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
88. GPC: Are they correct? (cont.)
88
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC (with Deadlock-freedom Theorem)
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators (with hints to OCaml DSL)
❖ Session Type merging
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and details of plumbings for polymorphic record extension)
❖ Benchmarks: Garbage collection matters
❖ Linearity monad
GPC key ingredients
Please ask me over beer!
89. GPC wrap up
89
Global Protocol Combinator: a DSL for writing global protocols
❖ Key Ingredients: Global Combinators
❖ Covers all basic MPST features (including full merging)
❖ Extensions: HTTP, and OAuth Example (on top of it), and more
OCamlM: fomalisation of a minimal programming language for GPC
❖ Subject Reduction, Operational Correspondence and Deadlock-freedom
❖ Types for global combinators
❖ Merging is a least upper bound in subtyping relation
Sauth
Spasswd
let oauth = (s --> c) login …
p1 pn
… … …
90. Future Work
90
A → B
B → C
A → B
• Deadlock-freedom proof on full global combinators
❖ Including more expressive ones (e.g. relaxed loop conditions)
❖ Scatter/Gather (broadcast), undirected internal choice, …
• Implementation in other programming languages
❖ TypeScript (structural subtyping from beginning, and will have recursive types as well)
❖ Haskell (automatically construct global combinators via type classes)
Thank you!
92. Loops are easy (for now)
92
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨?Slogin ⟩
93. Loops are easy (for now)
93
let oAuth = fix (λx. (S → C) login ((C → A) password ((A → C) auth x))
S
C
A
μx.⟨?Slogin ; !Spasswd; ?Sauth; x ⟩
μx. ⟨?Spasswd; !Sauth; x⟩
Sauth
Spasswd
Slogin
μx. ⟨?Slogin; x⟩
95. Input / output primitives and row-polymorphism in OCaml
95
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
96. Input / output primitives and row-polymorphism in OCaml
96
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
97. Input / output primitives and row-polymorphism in OCaml
97
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
98. Input / output primitives and row-polymorphism in OCaml
98
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
99. Input / output primitives and row-polymorphism in OCaml
99
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
100. Input / output primitives and row-polymorphism in OCaml
100
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
Inferred polymorphic variant type: it can have less receiving labels
(= in this case it must have password at least since there must be one)
101. Input / output primitives and row-polymorphism in OCaml
101
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
Inferred polymorphic variant type: it can have less receiving labels
(= in this case it must have password at least since there must be one)
Inferred object type: it can have more sending labels
102. Branching
102
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):
103. Branching
103
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
S will decide a branch, then C and A will follow
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):
104. Branching
104
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
S will decide a branch, then C and A will follow
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):An external choice is a pattern matching
(idiomatic OCaml)
105. Loops and delegations (1)
105
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
106. Loops and delegations (1)
106
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
107. Loops and delegations (1)
107
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
108. Loops and delegations (1)
108
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
val ch_S : < role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a
OCaml>
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
109. Loops and delegations (1)
109
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
val ch_S : < role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a
OCaml>
recursionrecursion
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
110. Loops and delegations (2)
110
let oauth_deleg =
(mst --> wrk) (msg >: get_prot s oauth2)
finish
Delegation doesn't need any special treatment, since OCaml will just infer the delegated type.
However, you can annotate labels with a delegated protocol, like this:
val ch_Mst :
< role_Wrk : < msg :
(< role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a *
close) out lin > >
OCaml>
Delegated type
111. Detecting protocol errors using types
111
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
NB: Branching is a source of concurrency issues
112. Detecting protocol errors using types
112
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
NB: Branching is a source of concurrency issues
113. Detecting protocol errors using types
113
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
Theorem: if a global type G is well-formed, its encoding
to a global combinator g =⟦G⟧ is well-typed in OCamlM.
NB: Branching is a source of concurrency issues
114. Detecting protocol errors using types
114
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
Theorem: if a global type G is well-formed, its encoding
to a global combinator g =⟦G⟧ is well-typed in OCamlM.
NB: Branching is a source of concurrency issues
Global Combinators have full expressivity of MPST Global Types
115. [Formalisation] OCamlM : a Minimal calculus for global combinators
Main results:
115
A calculus with structural subtyping, equi-recursive types and
i/o-typed channels
Theorem (Subject Reduction): if ⊢ e and e→* e' then ⊢ e'
Theorem (Operational Correspondence):
(Completeness)
(Soundness)
Corollary (Deadlock Freedom): If an MPST process P is
deadlock-free, OCamlM expression e=⟦P⟧ is deadlock-free.
116. Other features and Examples
✔ Branchings, loops, delegations
❖ Allows full merging in a branching (next slide)
✔ MPST as a wrapper
❖ Offers global protocol on top of HTTP, DNS, …
❖ Example: OAuth, DNS server, SMTP client, …
❖ Utilise concurrent/distributed libraries: Lwt (lightweight threads) and Unix IPC
✔ More Extensions
❖ Scatter/Gather (broadcast)
❖ Undirected choice (-nolive)
❖ Unbalanced Loops
116
B⊕m1 C⊕m2
B⊕m1C⊕m2
A → B
B → C
A → B
117. Full merging
117
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
Input labels are
polymorphic variantsA can have different
input branches
Example: A branch happens between S and C.
⇒ Merge A's two behaviours into one
Merging strategy Synopsis Implementations
Plain merging
All branches must have same
labels/continuation (restrictive)
Scalas et al.
(ECOOP 2017)
✔ Full merging
Different input labels/continuations
can be mergeable (more relaxed)
This work
118. • Benchmarks reflect our design decision to use
mutable long lived objects (e.g channel vectors)
❖ Our work: few mutable long lived objects, created at the start of the protocol
❖ State-of-the-art (linear-decomposition [Scala et.a]): many small channels, created on-demand
(during the protocol execution)
118
119. Benchmarks
• Comparison with Linear (Binary) Decomposition [Scalas et al., 2017]
❖ Translation from MPST to Linear Types
❖ Continuation Passing Style (CPS):
It creates (and exchanges) a fresh channel at each communication step
❖ Must be slower than us??
• Compete with ours in some cases (!), but CPS is slower in general
❖ OCaml's major GC is doing nice work
• Monad (static linearity checking with overhead) VS. Direct style (dynamic)
119
120. Put All Slides in right contexts!!
• Most surprising parts:
• (what is it) 簡単に?
programmers can write like this… select opponent role by method, then (a) send by method / (b) receive it and pattern match on variants.
Errors are detected like this… GC well-formedness errors and Local type conformance errors.
Bonus: recursive sessions, session subtyping and delegations are all free.
• (why/how gc-like typing is possible??)
(1) (why EPP is possible, it is operation on types!!: see onion and --> typing.)
(2) (why well-formedness checking is possible? What is well-formedness?: see typing rules)
• (key idea) タマネギ.2枚くらいにおさめる
• (how it is typed) --> typing and implementation (mention that OCaml do not have such first-class?)
• (how deadlock is detected: harder) choice, nondeterminisim and deadlock
choice is like an if-then-else. Two branches are merged into one.
(Sub)typing and global combinator typing prevents occasional wrong branching.
• (how it is imlpemented) lenses and first class record fields
• Choice_at typing and record extensions
❖ Least upper bound is merging
❖ We have more expressive GTs
❖ Subtyping and equi-recursive types
❖ Unguardedness and Unbalanced merging
• Linearity monad
• Deadlock freeness, syntax of local types, and undirected choice (sending and receiving)
• Benchmarks
• Meaning of type errors and relationship to deadlocks
❖ Mergeability and local type syntax
❖ Possibility to extension (i.e. non-directed merging)
❖ Why roles are record fields – what if it was variant tags
120
121. Channel Vectors: Inhabiting MPSTs as simple channel types
121
TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
122. Channel Vectors: Inhabiting MPSTs as simple channel types
122
sok scancel1
scancel2
sok scancel1
scancel2
Idea: Put simply-typed channels in a tree-like data structure
TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
123. Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
123
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
Pictorially:
124. Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
124
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
(scancel, )(sok, )
…
ok cancel
Pictorially:
125. Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
125
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s =
: ⟨B : ⟨ok: !(int*int)ו; cancel: !(bool) ×⟦…⟧⟩ ⟩
Provided that
• sok : Och, scancel : Och
(! is an output channel type)
<B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
(scancel, )(sok, )
…
ok cancel
Pictorially:
126. External choice is variant input
126
Variant input type: ?[ok_(boolו); cancel_(int× …)]
Variant type: [ok_(boolו); cancel_(int× …)]
("Either ok (with boolו) or cancel (with intׅ)")
("Receives either ok (with boolו) or cancel (with intׅ)")
cancel(_, )ok(_, )
scancel1sok
cancel
external choice
Pictorially: But how?
127. A Solution from Concurrent ML (Reppy, 1993)
127
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
128. A Solution from Concurrent ML (Reppy, 1993)
128
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
129. A Solution from Concurrent ML (Reppy, 1993)
129
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
130. A Solution from Concurrent ML (Reppy, 1993)
130
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
131. A Solution from Concurrent ML (Reppy, 1993)
131
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
132. Putting them altogether
132
(scancel, )(sok, )
ok cancel
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•}
choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)}
cancel(_, )
scancel2
133. Putting them altogether
133
(scancel, )(sok, )
ok cancel
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•}
choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)}
cancel(_, )
scancel2