<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://metamaya.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=KalmanKeri</id>
	<title>Metamaya - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://metamaya.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=KalmanKeri"/>
	<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/Special:Contributions/KalmanKeri"/>
	<updated>2026-04-21T10:57:49Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=350</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=350"/>
		<updated>2023-07-08T16:35:03Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Normal forms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with [[wikipedia:pi-calculus|π-calculus]], a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. &lt;br /&gt;
Rewrite rules can be applied to any matching subterm of a term. &lt;br /&gt;
A term is in normal form if no rewrite rule applies to any of its subterms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ . t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- . t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
('''Todo''': these rules don't implement idempotence of &amp;lt;math&amp;gt;|&amp;lt;/math&amp;gt; because commutativity is left out from the rules so equal terms don't always have a chance to &amp;quot;meet&amp;quot; on sides of &amp;lt;math&amp;gt;|&amp;lt;/math&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=349</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=349"/>
		<updated>2023-07-08T16:26:37Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Normal forms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with [[wikipedia:pi-calculus|π-calculus]], a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. &lt;br /&gt;
Rewrite rules can be applied to any matching subterm of a term. &lt;br /&gt;
A term is in normal form if no rewrite rule applies to any of its subterms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=348</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=348"/>
		<updated>2023-07-08T16:19:21Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Normal forms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with [[wikipedia:pi-calculus|π-calculus]], a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. &lt;br /&gt;
Rewrite rules can be applied to any matching subterm of a term. &lt;br /&gt;
A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=347</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=347"/>
		<updated>2023-06-25T08:07:39Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipe-calculus as a process calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with [[wikipedia:pi-calculus|π-calculus]], a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=346</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=346"/>
		<updated>2023-06-25T08:07:11Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with [[wikipedia:pi-calculus|π-calculus]], a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=345</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=345"/>
		<updated>2023-06-25T08:02:30Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The name of the calculus refers to the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not closely related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=344</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=344"/>
		<updated>2023-06-24T21:28:14Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* An example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The calculus was named after the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not directly related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; recursively runs a routine given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=343</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=343"/>
		<updated>2023-06-24T20:23:28Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* An example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The calculus was named after the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not directly related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=342</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=342"/>
		<updated>2023-06-24T20:16:40Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Prefixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The calculus was named after the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not directly related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
Intuitively, positive prefixes are outbound, while negative ones are inbound. &lt;br /&gt;
It is also useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=341</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=341"/>
		<updated>2023-06-24T20:08:45Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Terms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The calculus was named after the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not directly related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that is successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=340</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=340"/>
		<updated>2023-06-24T19:59:24Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is easy to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
The calculus was named after the ''pipe'' operator of Unix shells, and also alliterates with π-calculus, a popular process calculus, however they are not directly related.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=339</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=339"/>
		<updated>2023-05-28T17:07:54Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Normal forms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=338</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=338"/>
		<updated>2023-05-28T14:47:26Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipe and Unix pipelines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. They have remarkably similar properties. A shell pipeline connects programs that execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it tries to write to &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=337</id>
		<title>Work-in-progress</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=337"/>
		<updated>2023-05-25T22:06:20Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Encoding lambda calculus in pipe-calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is the temporary home of unfinished content.&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and Lambda calculus ==&lt;br /&gt;
&lt;br /&gt;
=== Encoding lambda calculus in pipe-calculus ===&lt;br /&gt;
&lt;br /&gt;
Lambda calculus is probably the most popular and well researched model of computation. It is an inevitable reference point for any calculus with computational capabilities. One of the most interesting questions is whether (and how) lambda calculus can be encoded into another calculus. Success of such task proves Turing-completeness of a calculus. Untyped pipe-calculus (PC) seems to be an easy target, but we have to be careful not to overlook subtle details. The encoding shown here is demonstrative and comes without a rigorous proof.&lt;br /&gt;
&lt;br /&gt;
By encoding I mean that normalisation of any valid lambda term can be replaced by a three step process. First, the lambda term is translated to a PC term. Second, this PC term is normalised and third, the normal form is translated back to a lambda term. If the lambda term has a normal form, a faithful encoding has to produce it (and only it). If normalisation of a lambda term does not halt, normalisation of the corresponding PC term shouldn't halt either. One also has to be aware of evaluation strategies and length of normal forms, something we neglect here.&lt;br /&gt;
&lt;br /&gt;
The obvious idea is to encode lambda abstraction as input prefixing and lambda application as the pipe operation. This comes with a limitation though. Because of the [[Pipe-calculus#Normal_forms|default rewrite rule]] for &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt;, there is no way to produce neutral applications, hence we can normalize only closed lambda terms, but it seems to be an acceptable trade-off if we are interested in programming languages. The translation is defined below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
\def\llbracket{[\![}&lt;br /&gt;
\def\rrbracket{]\!]}&lt;br /&gt;
\def\eq{\mathrel{=}\,}&lt;br /&gt;
&lt;br /&gt;
\llbracket \lambda x . t \rrbracket \eq &amp;amp; ?x . \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket t ~ u \rrbracket \eq &amp;amp; !\llbracket u \rrbracket . \bot \rhd \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket x \rrbracket \eq &amp;amp; x&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second step is normalisation. As translations utilize only a narrow fragment of PC, we can narrow down our term rewriting system too.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
!s . t \rhd ?x . u \rew &amp;amp; t \rhd u[s/x] \\&lt;br /&gt;
\bot \rhd t \rew &amp;amp; t \\&lt;br /&gt;
s \rhd t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Substitution rules are exactly the same as in lambda calculus.&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=336</id>
		<title>Work-in-progress</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=336"/>
		<updated>2023-05-25T21:38:02Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is the temporary home of unfinished content.&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and Lambda calculus ==&lt;br /&gt;
&lt;br /&gt;
=== Encoding lambda calculus in pipe-calculus ===&lt;br /&gt;
&lt;br /&gt;
Lambda calculus is probably the most popular and well researched model of computation. It is an inevitable reference point for any calculus with computational capabilities. One of the most interesting questions is whether (and how) lambda calculus can be encoded into another calculus. Success of such task proves Turing-completeness of a calculus. Untyped pipe-calculus (PC) seems to be an easy target, but we have to be careful not to overlook subtle details. The encoding shown here is demonstrative and comes without a rigorous proof.&lt;br /&gt;
&lt;br /&gt;
By encoding I mean that normalisation of any valid lambda term can be replaced by a three step process. First, the lambda term is translated to a PC term. Second, this PC term is normalised and third, the normal form is translated back to a lambda term. If the lambda term has a normal form, a faithful encoding has to produce it (and only it). If normalisation of a lambda term does not halt, normalisation of the corresponding PC term shouldn't halt either. One also has to be aware of evaluation strategies and length of normal forms, something we neglect here.&lt;br /&gt;
&lt;br /&gt;
The obvious idea is to encode lambda abstraction as input prefixing and lambda application as the pipe operation. This comes with a limitation though. Because of the [[Pipe-calculus#Normal_forms|default rewrite rule]] for &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt;, there is no way to produce neutral applications, hence we can normalize only closed lambda terms, but it seems to be an acceptable trade-off if we are interested in programming languages. The translation is defined below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
\def\llbracket{[\![}&lt;br /&gt;
\def\rrbracket{]\!]}&lt;br /&gt;
\def\eq{\mathrel{=}\,}&lt;br /&gt;
&lt;br /&gt;
\llbracket \lambda x . t \rrbracket \eq &amp;amp; ?x . \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket t ~ u \rrbracket \eq &amp;amp; !\llbracket u \rrbracket . \bot \rhd \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket x \rrbracket \eq &amp;amp; x&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=335</id>
		<title>Work-in-progress</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=335"/>
		<updated>2023-05-25T21:37:05Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Encoding lambda calculus in pipe-calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is temporary home of immature content.&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and Lambda calculus ==&lt;br /&gt;
&lt;br /&gt;
=== Encoding lambda calculus in pipe-calculus ===&lt;br /&gt;
&lt;br /&gt;
Lambda calculus is probably the most popular and well researched model of computation. It is an inevitable reference point for any calculus with computational capabilities. One of the most interesting questions is whether (and how) lambda calculus can be encoded into another calculus. Success of such task proves Turing-completeness of a calculus. Untyped pipe-calculus (PC) seems to be an easy target, but we have to be careful not to overlook subtle details. The encoding shown here is demonstrative and comes without a rigorous proof.&lt;br /&gt;
&lt;br /&gt;
By encoding I mean that normalisation of any valid lambda term can be replaced by a three step process. First, the lambda term is translated to a PC term. Second, this PC term is normalised and third, the normal form is translated back to a lambda term. If the lambda term has a normal form, a faithful encoding has to produce it (and only it). If normalisation of a lambda term does not halt, normalisation of the corresponding PC term shouldn't halt either. One also has to be aware of evaluation strategies and length of normal forms, something we neglect here.&lt;br /&gt;
&lt;br /&gt;
The obvious idea is to encode lambda abstraction as input prefixing and lambda application as the pipe operation. This comes with a limitation though. Because of the [[Pipe-calculus#Normal_forms|default rewrite rule]] for &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt;, there is no way to produce neutral applications, hence we can normalize only closed lambda terms, but it seems to be an acceptable trade-off if we are interested in programming languages. The translation is defined below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
\def\llbracket{[\![}&lt;br /&gt;
\def\rrbracket{]\!]}&lt;br /&gt;
\def\eq{\mathrel{=}\,}&lt;br /&gt;
&lt;br /&gt;
\llbracket \lambda x . t \rrbracket \eq &amp;amp; ?x . \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket t ~ u \rrbracket \eq &amp;amp; !\llbracket u \rrbracket . \bot \rhd \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket x \rrbracket \eq &amp;amp; x&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=334</id>
		<title>Work-in-progress</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Work-in-progress&amp;diff=334"/>
		<updated>2023-05-25T21:16:28Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: Created page with &amp;quot;This page is temporary home of immature content.  == Pipe-calculus and Lambda calculus ==  === Encoding lambda calculus in pipe-calculus ===  Lambda calculus is probably the most popular and well researched model of computation. It is an inevitable reference point for any calculus with computational capabilities. One of the most interesting questions is whether (and how) lambda calculus can be encoded into another calculus. Success of this task proves Turing-completeness...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is temporary home of immature content.&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and Lambda calculus ==&lt;br /&gt;
&lt;br /&gt;
=== Encoding lambda calculus in pipe-calculus ===&lt;br /&gt;
&lt;br /&gt;
Lambda calculus is probably the most popular and well researched model of computation. It is an inevitable reference point for any calculus with computational capabilities. One of the most interesting questions is whether (and how) lambda calculus can be encoded into another calculus. Success of this task proves Turing-completeness. Pipe-calculus (PC) seems to be an easy target, but we have to be careful not to overlook subtle details. The encoding shown here is demonstrative and comes without rigorous proof.&lt;br /&gt;
&lt;br /&gt;
By encoding I mean that normalisation of any valid lambda term can be replaced by a three step process. First, the lambda term is translated to a PC term. Second, this PC term is normalised and third, the normal form is translated back to a lambda term. If the lambda term has a normal form, a faithful encoding has to produce it (and only it). If normalisation of a lambda term does not halt, normalisation of the corresponding PC term shouldn't halt either. One also has to be aware of evaluation strategies and length of normal forms, something we neglect here.&lt;br /&gt;
&lt;br /&gt;
The obvious idea is to encode lambda abstraction as input prefixing and lambda application as the pipe operation. This comes with a limitation though. Because of the default rewrite rule for ''pipe'', there is no way to produce neutral applications, hence we can normalize only closed lambda terms, but it seems acceptable for programming languages. The translation is defined below.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
\def\llbracket{[\![}&lt;br /&gt;
\def\rrbracket{]\!]}&lt;br /&gt;
\def\eq{\mathrel{=}\,}&lt;br /&gt;
&lt;br /&gt;
\llbracket \lambda x . t \rrbracket \eq &amp;amp; ?x . \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket t ~ u \rrbracket \eq &amp;amp; !\llbracket u \rrbracket . \bot \rhd \llbracket t \rrbracket \\&lt;br /&gt;
\llbracket x \rrbracket \eq &amp;amp; x&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=333</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=333"/>
		<updated>2023-05-25T13:00:32Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Analogies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it writes to its &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=332</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=332"/>
		<updated>2023-05-25T07:44:04Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Terms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Failure of one branch does not affect the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it writes to its &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=331</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=331"/>
		<updated>2023-05-25T07:41:58Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Exclusive choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples of synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it writes to its &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=330</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=330"/>
		<updated>2023-05-25T07:41:00Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Exclusive choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it writes to its &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=329</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=329"/>
		<updated>2023-05-25T07:35:43Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipe and Unix pipelines */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
If &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; continues to run, but if &amp;lt;math&amp;gt;P2&amp;lt;/math&amp;gt; exits, &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; will exit too&amp;lt;ref&amp;gt;The process will exit next time when it writes to its &amp;lt;code&amp;gt;stdout&amp;lt;/code&amp;gt;, at least if the default &amp;lt;code&amp;gt;SIGPIPE&amp;lt;/code&amp;gt; handler is not replaced by the user.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Although Unix processes can handle multiple input and output streams, only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=328</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=328"/>
		<updated>2023-05-25T07:23:13Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Prefixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In some applications it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=327</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=327"/>
		<updated>2023-05-25T07:19:54Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Terms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?x \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=326</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=326"/>
		<updated>2023-05-25T07:18:12Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Motivation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming with text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=325</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=325"/>
		<updated>2023-05-25T07:15:07Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Variants and computational power */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be created by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a design goal that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=324</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=324"/>
		<updated>2023-05-25T07:07:13Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipe-calculus and process calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several one of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=323</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=323"/>
		<updated>2023-05-25T07:06:10Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Recognition and interpretation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=322</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=322"/>
		<updated>2023-05-25T07:05:20Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?x . u = t \rhd u[s/x]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=321</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=321"/>
		<updated>2023-05-24T23:59:02Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Prefixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact. In the zeroth-order calculus only synchronisation is present.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=320</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=320"/>
		<updated>2023-05-24T23:50:11Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars?)&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection (commutative, idempotent conjunction)&lt;br /&gt;
* Replication&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=319</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=319"/>
		<updated>2023-05-24T23:40:25Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipe-calculus and process calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behaviour of a system. The word ''algebra'' denotes an algebraic approach in talking about behaviour, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behaviour (actions, events) and formers of compound processes (operations, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
=== Interaction and behaviour ===&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes are treated in one of two settings: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may ''interact'' with each other and together they produce a compound process.&lt;br /&gt;
In the other setting a single process is examined by placing it into a (not strictly specified) environment which is able to interact with the process. In this case the emphasis is placed on the observable ''behaviour'' of the process that is the possible sequences of actions performed by the process. &lt;br /&gt;
&lt;br /&gt;
=== Pipe-calculus as a process calculus ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behaviour (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=318</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=318"/>
		<updated>2023-05-24T23:10:09Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Equational theory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose branches are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=317</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=317"/>
		<updated>2023-05-24T23:09:24Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each branch of the left side is paired with each branch of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=316</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=316"/>
		<updated>2023-05-24T23:08:40Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Terms */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one branch executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other branch executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of branches overlap in time. If one of the branches fails, the composite process is replaced by the other branch.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=315</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=315"/>
		<updated>2023-05-24T23:07:54Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* An example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current branch of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one branch runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another branch runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=314</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=314"/>
		<updated>2023-05-24T22:56:40Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Analogies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore possible solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, none of them is outstanding.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=313</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=313"/>
		<updated>2023-05-24T22:52:04Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Exclusive choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction with another process leaves at most one active branch.&lt;br /&gt;
These are examples to synchronization-guarded choice. They allow for the encoding of sum types (with positive guards) and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions (with negative guards) in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=312</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=312"/>
		<updated>2023-05-24T22:31:06Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipeline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction leaves at most one active branch.&lt;br /&gt;
&lt;br /&gt;
This form is called synchronization-guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=311</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=311"/>
		<updated>2023-05-24T22:29:51Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Prefixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and kind.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Prefixes are also the basic units of interaction. Prefixes of the same kind and opposite polarity can interact.&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction leaves at most one active branch.&lt;br /&gt;
&lt;br /&gt;
This form is called synchronization-guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=310</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=310"/>
		<updated>2023-05-24T22:23:41Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Exclusive choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
Given a set of distinct atoms &amp;lt;math&amp;gt;{ a_1,...a_n }&amp;lt;/math&amp;gt; and process terms &amp;lt;math&amp;gt;s_1,...s_n, t_1,...t_n&amp;lt;/math&amp;gt;, all subterms of &amp;lt;math&amp;gt;a_1^+ . s_1 \mid ... \mid a_n^+ . s_n  \mid a_1^- . t_1 \mid ... \mid a_n^- . t_n&amp;lt;/math&amp;gt; are ''exclusive'' choices, since all possible interaction leaves at most one active branch.&lt;br /&gt;
&lt;br /&gt;
This form is called synchronization-guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=309</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=309"/>
		<updated>2023-05-24T21:19:13Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches are indistinguishable. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=308</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=308"/>
		<updated>2023-05-24T21:15:53Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, all others remain active. In other words, failure is local to branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If one of the branches succeeds, the choice succeeds too, eliminating all remaining branches.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \top = \top&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identical branches cannot be distinguished. In the following example, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed only once.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid s = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=307</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=307"/>
		<updated>2023-05-24T21:02:25Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Choice */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
Choice is a forking process. &amp;lt;math&amp;gt;s \mid t&amp;lt;/math&amp;gt; has two branches that exist side by side.&lt;br /&gt;
Both &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are ready for interaction, however they can't communicate with each other. Both branches participate in the same interaction but they evolve independently.&lt;br /&gt;
This is different from systems where alternatives are exclusive or they are examined one by one. We can say that choice is ''laid out in space''&amp;lt;ref&amp;gt;This suggestive phrasing is borrowed from Lennart Augustsson et al.: [https://simon.peytonjones.org/assets/pdfs/verse-March23.pdf The Verse Calculus: a Core Calculus for Functional Logic Programming].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If one of the branches fail, the other remains active.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s \mid \bot = s&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* laid out in space&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analysis&lt;br /&gt;
&lt;br /&gt;
==== Analogies ====&lt;br /&gt;
&lt;br /&gt;
Practical concepts that share some properties with choice are:&lt;br /&gt;
&lt;br /&gt;
* The Unix [[Wikipedia:Fork_(system_call)|fork system call]] - as both forks inherit the same environment and the failure of one fork does not affect the other one.&lt;br /&gt;
* Branches in a version control system - branches are often created to explore solutions and successful solutions are merged with the main branch.&lt;br /&gt;
&lt;br /&gt;
In both analogies, branches may exist side by side. However branches of a choice combinator are all equal, there is no main branch between them.&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=306</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=306"/>
		<updated>2023-05-24T19:57:17Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Connection with process calculus */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Pipe-calculus and process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=305</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=305"/>
		<updated>2023-05-24T19:55:36Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Formal Definition */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Connection with process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=304</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=304"/>
		<updated>2023-05-24T19:53:27Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term output by the left side is available in the continuation of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with [[Wikipedia:Process_calculus#Reduction_semantics|reduction semantics]] of process calculi on Wikipedia.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal Definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Connection with process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=303</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=303"/>
		<updated>2023-05-24T19:44:35Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Prefixes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are the basic units of behavior (they are called ''actions'' in process algebra). In pipe-calculus actions can only occur together with a continuation.&lt;br /&gt;
Actions can be classified by polarity and mode.&lt;br /&gt;
In some applications of the calculus it is useful to think of positive prefixes as data and negative prefixes as programs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;  style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! Synchronisation&lt;br /&gt;
! Communication&lt;br /&gt;
|-&lt;br /&gt;
! Positive&lt;br /&gt;
| &amp;lt;math&amp;gt;a^+ . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;!s . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Negative&lt;br /&gt;
| &amp;lt;math&amp;gt;a^- . t&amp;lt;/math&amp;gt;&lt;br /&gt;
| &amp;lt;math&amp;gt;?x . t&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term sent by the left side is available on the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with the relevant section on [[Wikipedia:Process_calculus#Reduction_semantics|Wikipedia]].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure of the current fork.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal Definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Connection with process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=302</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=302"/>
		<updated>2023-05-24T19:15:35Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Equational theory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are basic units of behavior (called ''actions'' in process algebra). In pipe-calculus they can only occur together with a continuation. &lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term sent by the left side is available on the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with the relevant section on [[Wikipedia:Process_calculus#Reduction_semantics|Wikipedia]].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure of the current fork.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal Definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following structural laws are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Connection with process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
	<entry>
		<id>https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=301</id>
		<title>Pipe-calculus</title>
		<link rel="alternate" type="text/html" href="https://metamaya.org/wiki/index.php?title=Pipe-calculus&amp;diff=301"/>
		<updated>2023-05-24T19:09:07Z</updated>

		<summary type="html">&lt;p&gt;KalmanKeri: /* Pipeline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Pipe-calculus''' is a universal model of computation closely related to [[Wikipedia:process_calculus|process calculus]], [[Wikipedia:lambda_calculus|lambda calculus]] and [[Wikipedia:Formal_grammar|formal grammars]]. &lt;br /&gt;
One of its distinctive features is the inclusion of syntactic symbols, so it is possible to express program structure and complex data types using only the built-in constructs.&lt;br /&gt;
&lt;br /&gt;
Pure pipe-calculus is untyped. Construction of a [[ideas_for_a_type_system|type system]] is in the exploration phase, placing the focus on well-typed communication of programs.&lt;br /&gt;
&lt;br /&gt;
Although the core calculus is sufficiently expressive to be used as a programming language, with added [[Syntax_sugar_(Pipe-calculus)|syntax sugar]] it can be the basis of various typed or untyped programming languages.&lt;br /&gt;
Its characteristic features like I/O and stream orientation make pipe-calculus a suitable choice even for scripting languages. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #f4f4f4; border: 1px solid #e8e8e8; padding: 0.3em 0.7em 0.3em 0.7em;&amp;quot;&amp;gt;&lt;br /&gt;
'''Note:''' Pipe-calculus is a work in progress. This wiki page reflects the current status of the project and details may well change over time.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Motivation ===&lt;br /&gt;
&lt;br /&gt;
Development of pipe-calculus started with the idea that syntax should be a first class element of programming languages as well as formation rules are integral part of logical systems. A language like that is able to interpret complex input without using a parser library. Pipe-calculus is a minimal language with this capability.&lt;br /&gt;
&lt;br /&gt;
On the practical side pipe-calculus is inspired by shell programming, which is largely based on text streams and stream processing tools. Indeed the idea of the ''pipe'' combinator comes from shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== An example ===&lt;br /&gt;
&lt;br /&gt;
To get a taste of pipe-calculus, consider a program that adds two natural numbers encoded in [[wikipedia:Unary_numeral_system|unary numeral system]]. Suppose that we send both numbers over a stream as a series of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s terminated by an &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. Our example language consists of the following expressions.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;match s&amp;lt;/code&amp;gt; expects that the next symbol of the input stream is &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt;. On failure the current fork of the program is aborted.&lt;br /&gt;
* &amp;lt;code&amp;gt;write s&amp;lt;/code&amp;gt; appends the symbol &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; to the output stream.&lt;br /&gt;
* &amp;lt;code&amp;gt;run x&amp;lt;/code&amp;gt; runs a program given its name.&lt;br /&gt;
* &amp;lt;code&amp;gt;p ; q&amp;lt;/code&amp;gt; runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; then runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; unless &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt; fails.&lt;br /&gt;
* &amp;lt;code&amp;gt;p | q&amp;lt;/code&amp;gt; forks the execution of the program so that one fork runs &amp;lt;code&amp;gt;p&amp;lt;/code&amp;gt;, another fork runs &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt;, sharing the same input and output stream.&lt;br /&gt;
&lt;br /&gt;
Start by writing a routine that copies a natural number from the input to the output.&lt;br /&gt;
&lt;br /&gt;
 passNat = match 1; write 1; run passNat | match end; write end&lt;br /&gt;
&lt;br /&gt;
Now we can write the program that writes the sum of two numbers to the output.&lt;br /&gt;
&lt;br /&gt;
 addNat = match 1; write 1; run addNat | match end; run passNat&lt;br /&gt;
&lt;br /&gt;
The program terminates after matching and writing out the second &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; symbol. It skips the first &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; that terminates the first number and copies everything else.&lt;br /&gt;
Effectively it concatenates two sequences of &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;s. If any other symbol occurs in the input stream, the program fails.&lt;br /&gt;
&lt;br /&gt;
This language is obviously too weak. We can write simple filters, but we can't even check the equality of two numbers. In order to do it, we need a method that allows the first number to be accumulated and read back symbol by symbol as we read the second number.&lt;br /&gt;
Pipe-calculus can be seen as a framework to study the required extensions that turn this tiny language into a practical programming language.&lt;br /&gt;
&lt;br /&gt;
=== Connection with other fields ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus is presented as a process calculus. Although it significantly differs from typical process calculi, it still lends itself to this style of presentation.&lt;br /&gt;
Its development is also inspired by&lt;br /&gt;
[[Wikipedia:Higher-order_logic_programming|higher-order logic programming]],&lt;br /&gt;
[[Wikipedia:Automata_theory|automata theory]],&lt;br /&gt;
[[Wikipedia:Type_theory|type theory]] (up to the [[Wikipedia:Lambda_cube|lambda-cube]]) and &lt;br /&gt;
[[Wikipedia:Effect_system|algebraic effects]]&lt;br /&gt;
&amp;lt;ref&amp;gt;&lt;br /&gt;
Matija Pretnar: [https://www.eff-lang.org/handlers-tutorial.pdf An Introduction to Algebraic Effects and Handlers]&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In certain cases the connection can be made more precise.&lt;br /&gt;
&lt;br /&gt;
* Programs written in pipe-calculus can recognize and generate words of formal languages encoded as terms.&lt;br /&gt;
* Untyped lambda calculus can be translated to a subset of higher-order pipe-calculus (to be specified later).&lt;br /&gt;
&lt;br /&gt;
=== Variants and computational power ===&lt;br /&gt;
&lt;br /&gt;
The most basic variant of the calculus that lacks any scoped constructs is called '''zeroth-order''' as a reference to [[Wikipedia:Zeroth-order_logic|zeroth-order logic]].&lt;br /&gt;
Somewhat surprisingly, even the zeroth-order calculus has a limited computational power.&lt;br /&gt;
In the '''higher-order''' calculus there are lexically scoped variables that can bind arbitrary terms. Intermediate variants can be constructed by extending the basic calculus with new constructs. Determining the computational power of specific variants of the calculus is of interest.&lt;br /&gt;
&lt;br /&gt;
It is an observation and also a driving force of development that specific variants of the calculus can recognize specific classes of formal languages in the [[Wikipedia:Chomsky_hierarchy|Chomsky hierarchy]]. For example it is assumed that the zeroth-order calculus with top level recursion can encode [[Wikipedia:Finite-state_machine|finite-state machines]] and as a consequence it can recognize regular languages.&lt;br /&gt;
&lt;br /&gt;
== Informal description ==&lt;br /&gt;
&lt;br /&gt;
=== Terms ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\dot{.}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\pass{\textbf{pass}}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Pipe-calculus terms are also called '''processes''' to emphasize their interactive, behavioral aspect. Each process has a conceptual '''input''' and '''output''' which are implicit in the rules. Output of one process can be connected to the input of another one.&lt;br /&gt;
Some terms contain '''atoms''' which are unscoped and uninterpreted symbols. In grammatical context one can think of atoms as ''tokens''.&lt;br /&gt;
&lt;br /&gt;
The following terms are available in pipe-calculus.&lt;br /&gt;
&lt;br /&gt;
* ''synchronisation'', where&lt;br /&gt;
** ''negative literal prefixing'' &amp;lt;math&amp;gt;a^- \dot s&amp;lt;/math&amp;gt; is a process that expects an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; to be signalled on its input. If the expectation is fulfilled, the process  proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, otherwise it fails.&lt;br /&gt;
** ''positive literal prefixing'' &amp;lt;math&amp;gt;a^+ \dot s&amp;lt;/math&amp;gt; is a process that signals an atom &amp;lt;math&amp;gt;a&amp;lt;/math&amp;gt; on its output before proceeding as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''communication'', where&lt;br /&gt;
** ''input prefixing'' &amp;lt;math&amp;gt;?n \dot s&amp;lt;/math&amp;gt; is a process that receives a term on its input. On success, it proceeds as &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; binding the name &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; to the received term.&lt;br /&gt;
** ''output prefixing'' &amp;lt;math&amp;gt;!s \dot t&amp;lt;/math&amp;gt; is a process that sends a term &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to its output before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;.&lt;br /&gt;
* ''sequence'' &amp;lt;math&amp;gt;s \seq t&amp;lt;/math&amp;gt; is a composite process that executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; before proceeding as &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; unless &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails.&lt;br /&gt;
* ''choice'' &amp;lt;math&amp;gt;s \alt t&amp;lt;/math&amp;gt; is a forking process where one fork executes &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; while the other fork executes &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Execution of the forks overlap in time. If one of the forks fails, the composite process is replaced by the other fork.&lt;br /&gt;
* ''pipeline'' &amp;lt;math&amp;gt;s \pipe t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional, left to right data flow between its components.&lt;br /&gt;
* ''top'' &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; is a process that successfully terminated.&lt;br /&gt;
* ''bottom'' &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; is also a terminated process. In certain contexts it denotes failure.&lt;br /&gt;
&lt;br /&gt;
=== Prefixes ===&lt;br /&gt;
&lt;br /&gt;
''Prefixes'' are basic units of behavior (called ''actions'' in process algebra). In pipe-calculus they can only occur together with a continuation. &lt;br /&gt;
&lt;br /&gt;
=== Sequence ===&lt;br /&gt;
&lt;br /&gt;
Sequences bring the concept of temporal order to pipe-calculus. In &amp;lt;math&amp;gt;s \mathrel{;} t&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed before &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; (more precisely, the behavior of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is observed before the behavior of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;).&lt;br /&gt;
If &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; fails (it reduces to &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;), &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is not executed at all and the sequence fails.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bot \mathrel{;} t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand succeeds, the right operand follows.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\top \mathrel{;} t = t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;math&amp;gt;s ; s&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is executed twice. In other words, sequence is not idempotent.&lt;br /&gt;
Logically &amp;lt;math&amp;gt;;&amp;lt;/math&amp;gt; has common properties with non-commutative (shortcut) conjunction.&lt;br /&gt;
&lt;br /&gt;
Prefixed forms also obey this temporal ordering: the behavior of the prefix is observed before the behavior of the continuation&amp;lt;ref&amp;gt;Wikipedia implies that prefixed forms are specialized forms of sequential composition: &amp;quot;In process calculi, the sequentialisation operator is usually integrated with input or output, or both.&amp;quot; ([[Wikipedia:Process_calculus#Sequential_composition|Process calculus]] on Wikipedia)&lt;br /&gt;
&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Choice ===&lt;br /&gt;
&lt;br /&gt;
* fork - join&lt;br /&gt;
* failure is local to forks&lt;br /&gt;
* forks may overlap&lt;br /&gt;
* but identical forks cannot be distinguished&lt;br /&gt;
* choice and mathematical case analisys&lt;br /&gt;
&lt;br /&gt;
==== Exclusive choice ====&lt;br /&gt;
&lt;br /&gt;
One can make choices mutually exclusive by limiting themeselves to trees of choices where each leaf of the tree is one of the forms &amp;lt;math&amp;gt;a^+ . s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;a^- . s&amp;lt;/math&amp;gt; [and all atoms are different]. This is an example of guarded choice[]. It allows for the encoding of sum types and the corresponding &amp;lt;math&amp;gt;case&amp;lt;/math&amp;gt; expressions in strongly typed functional languages.&lt;br /&gt;
&lt;br /&gt;
=== Pipeline ===&lt;br /&gt;
&lt;br /&gt;
After discussing sequence and choice, the pipe combinator is the first where interaction occurs between processes.&lt;br /&gt;
&amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; is a composite process that enforces unidirectional data flow between its components. Input of the composite process is forwarded to the input of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;, output of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; is connected to the input of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; and output of &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is forwarded to the output of the composite process, according to the following diagram.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\underset{s \rhd t}{\boxed{\to \boxed{s} \to \boxed{t} \to}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compared to the parallel composition &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; in [[Wikipedia:π-calculus|π-calculus]], &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; can be classified as unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
&lt;br /&gt;
If the operands are prefixed with matching literals, synchronisation occurs and both sides make progress.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd a^- . t = s \rhd t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the left operand is an output prefix and the right operand is an input prefix, communication occurs and both sides make progress. The term sent by the left side is available on the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;!s . t \rhd ?n . u = t \rhd u[s/n]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arguably these are the key rules of pipe-calculus&amp;lt;ref&amp;gt;Compare with the relevant section on [[Wikipedia:Process_calculus#Reduction_semantics|Wikipedia]].&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Any other combination of prefixes leads to failure of the current fork.&lt;br /&gt;
The following example fails because synchronisation cannot occur between different atoms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;a^+ . s \rhd b^- . t = \bot&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If any of the arguments is a choice, each fork of the left side is paired with each fork of the right side.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;r \mid s \rhd t \mid u = (r \rhd t) \mid (r \rhd u) \mid (s \rhd t) \mid (s \rhd u)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Pipe and Unix pipelines ====&lt;br /&gt;
&lt;br /&gt;
A [[Wikipedia:Pipeline_(Unix)|pipeline]] in Unix shell programming is a good analogy for the pipe combinator. Piped programs execute concurrently. In &amp;lt;math&amp;gt;P1 | P2&amp;lt;/math&amp;gt; it cannot occur that the output of &amp;lt;math&amp;gt;P1&amp;lt;/math&amp;gt; directly reaches the output of the pipeline.&lt;br /&gt;
Unix processes can handle more than one input and output streams, but only the standard input and output streams are passed on through the pipe.&lt;br /&gt;
&lt;br /&gt;
==== Recognition and interpretation ====&lt;br /&gt;
&lt;br /&gt;
One can also think of &amp;lt;math&amp;gt;s \rhd t&amp;lt;/math&amp;gt; in a syntactic setting. In this case &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; represents ''input'' or ''source'', while &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; plays the role of a ''recognizer'', ''parser'' or ''interpreter''.&lt;br /&gt;
&lt;br /&gt;
== Formal Definition ==&lt;br /&gt;
&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\pos{\mathsf{pos}~}&lt;br /&gt;
\def\neg{\mathsf{neg}~}&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
\def\rule{ ::= ~}&lt;br /&gt;
&lt;br /&gt;
\begin{alignat}{3}&lt;br /&gt;
&amp;amp; \mbox{Atoms}~        &amp;amp; a, b \rule &amp;amp; \mathsf{A} \mid \mathsf{B} \mid \mathsf{'foo} \mid \mathsf{'bar} \mid \mathsf{'+} \mid \mathsf{'*} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Variables}~    &amp;amp; x, y \rule &amp;amp; \mathsf{a} \mid \mathsf{b} \mid ... \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Prefixes}~     &amp;amp; p, q \rule &lt;br /&gt;
         &amp;amp; ~ a^+             &amp;amp; &amp;amp; \text{Positive literal (signal)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ a^-             &amp;amp; &amp;amp; \text{Negative literal (match)} \\ &lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ ?x              &amp;amp; &amp;amp; \text{Abstraction (input)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ !s              &amp;amp; &amp;amp; \text{Argument (output)} \\&lt;br /&gt;
&lt;br /&gt;
&amp;amp; \mbox{Terms}~        &amp;amp; s, t \rule&lt;br /&gt;
         &amp;amp; ~ p . s            &amp;amp; &amp;amp; \text{Prefix operator} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \seq t         &amp;amp; &amp;amp; \text{Sequential composition} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \mathsf{|} t   &amp;amp; &amp;amp; \text{Choice} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ s \pipe t        &amp;amp; &amp;amp; \text{Pipe (interpretation)} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \top             &amp;amp; &amp;amp; \text{Termination, also success} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ \bot             &amp;amp; &amp;amp; \text{Termination, also failure} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ x                &amp;amp; &amp;amp; \text{Variable} \\&lt;br /&gt;
&amp;amp; &amp;amp; \mid &amp;amp; ~ (s)              &amp;amp; &amp;amp; \text{Grouping} \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Operator summary&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Symbol&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Associativity&amp;lt;ref&amp;gt;&lt;br /&gt;
Notice that ''left or right associativity'' is a grammatical property of a binary operator,&lt;br /&gt;
which differs from the mathematical ''associativity'' of the respective operation.&lt;br /&gt;
Even associative operations may be represented by left or right associative operators.&lt;br /&gt;
See [[Wikipedia:Operator_associativity|Operator associativity]].&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot;| Precedence&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\seq&amp;lt;/math&amp;gt; || right || highest&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt; || right || &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;math&amp;gt;\rhd&amp;lt;/math&amp;gt; || right || lowest&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Equational theory ===&lt;br /&gt;
&lt;br /&gt;
Pipe-calculus can be described as a process algebra&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
.&lt;br /&gt;
The following identities are satisfied by all &amp;lt;math&amp;gt;s, t, u&amp;lt;/math&amp;gt; pipe-calculus terms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\eq{ = ~}&lt;br /&gt;
&amp;lt;/math&amp;gt;Sequential composition is associative with left neutral element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt; and left absorbing element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \seq t) \seq u \eq &amp;amp; s \seq (t \seq u)  \\&lt;br /&gt;
\top \seq t \eq &amp;amp; t \\&lt;br /&gt;
\bot \seq t \eq &amp;amp; \bot \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choice is associative, commutative and idempotent with neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \alt u \eq &amp;amp; s \alt (t \alt u)  \\&lt;br /&gt;
s \alt t \eq &amp;amp; t \alt s \\&lt;br /&gt;
s \alt s \eq &amp;amp; s \\&lt;br /&gt;
\top \alt t \eq &amp;amp; \top \\&lt;br /&gt;
\bot \alt t \eq &amp;amp; t \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequential composition is right distributive over choice.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(s \alt t) \seq u \eq &amp;amp; s \seq u \alt t \seq u &lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pipe has left neutral element &amp;lt;math&amp;gt;\bot&amp;lt;/math&amp;gt; and right absorbing element &amp;lt;math&amp;gt;\top&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\bot \pipe t \eq &amp;amp; t \\&lt;br /&gt;
s \pipe \top \eq &amp;amp; \top \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Todo: pipe is also associative for ''well behaving'' operands. A process whose forks are all of the same prefixed form are certainly well behaving.&lt;br /&gt;
&lt;br /&gt;
=== Normal forms ===&lt;br /&gt;
&lt;br /&gt;
Normal form of pipe-calculus terms is defined by a term rewriting system&amp;lt;ref name=&amp;quot;Fokkink&amp;quot;/&amp;gt;. A term is in normal form if no rewrite rule applies to it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\def\seq{\mathrel{;}}&lt;br /&gt;
\def\alt{\mid}&lt;br /&gt;
\def\pipe{\rhd}&lt;br /&gt;
\def\in{\,?}&lt;br /&gt;
\def\out{!}&lt;br /&gt;
\def\rew{\mathrel{\Rightarrow}\,}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{1}&lt;br /&gt;
(s \seq t) \seq u \rew &amp;amp; s \seq (t \seq u) \\&lt;br /&gt;
(s \alt t) \seq u \rew &amp;amp; s \seq u \alt t \seq u \\&lt;br /&gt;
\top \seq s \rew &amp;amp; s \\&lt;br /&gt;
\bot \seq s \rew &amp;amp; \bot \\&lt;br /&gt;
\\&lt;br /&gt;
(s \alt t) \alt u \rew &amp;amp; s \alt (t \alt u) \\&lt;br /&gt;
a^+ . s \alt a^+ \seq t \rew &amp;amp; a^+ . (s \alt t) \\&lt;br /&gt;
a^- . s \alt a^- \seq t \rew &amp;amp; a^- . (s \alt t) \\&lt;br /&gt;
\bot \alt s \rew &amp;amp; s \\&lt;br /&gt;
s \alt \bot \rew &amp;amp; s \\&lt;br /&gt;
\top \alt s \rew &amp;amp; \top \\&lt;br /&gt;
s \alt \top \rew &amp;amp; \top \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While all other rules are syntax directed, rules for &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; have to be attempted in the listed order for the following reasons.&lt;br /&gt;
&lt;br /&gt;
# The processes &amp;lt;math&amp;gt;a^- . s \pipe a^+ . t&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\in x . s \pipe \out t . u&amp;lt;/math&amp;gt; behave differently depending on the order of rule application, even if their normal forms are identical.&lt;br /&gt;
# The process &amp;lt;math&amp;gt;r \alt s \pipe t \alt u&amp;lt;/math&amp;gt; produces subresults in different order depending of the order of rule application. Explicit application order avoids nondeterminism in both cases.&lt;br /&gt;
# We need a default rule that fails in order to ensure that &amp;lt;math&amp;gt;\pipe&amp;lt;/math&amp;gt; never occurs in normal forms&amp;lt;ref&amp;gt;The default case allows for embedding synchronisation failure in the object language, so it can be captured by &amp;lt;math&amp;gt;\mid&amp;lt;/math&amp;gt;.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{alignat}{2}&lt;br /&gt;
a^+ . s \pipe a^- . t \rew &amp;amp; s \pipe t \\&lt;br /&gt;
\out s . t \pipe \in x . u \rew &amp;amp; t \pipe u[s/x] \\&lt;br /&gt;
r \alt s \pipe t \alt u \rew &amp;amp; (r \pipe t \alt u) \alt (s \pipe t \alt u) \\&lt;br /&gt;
s \alt t \pipe u \rew &amp;amp; (s \pipe u) \alt (t \pipe u) \\&lt;br /&gt;
s \pipe t \alt u \rew &amp;amp; (s \pipe t) \alt (s \pipe u) \\ &lt;br /&gt;
\bot \pipe t \rew &amp;amp; t \\&lt;br /&gt;
s \pipe \top \rew &amp;amp; \top \\&lt;br /&gt;
s \pipe t \rew &amp;amp; \bot &amp;amp; \\&lt;br /&gt;
\end{alignat}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that finding a matching rewriting rule does not require checking the equality of terms, only of atoms.&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
* Recursion (μ-recursion, top level recursion, regular grammars)&lt;br /&gt;
* Stack (context-free grammars)&lt;br /&gt;
* Guarded choice&lt;br /&gt;
* Ordered choice (PEG, backtracking, local context)&lt;br /&gt;
* Intersection&lt;br /&gt;
&lt;br /&gt;
== Connection with process calculus ==&lt;br /&gt;
&lt;br /&gt;
'''[[wikipedia:process_calculus | Process calculi]]''' (or '''process algebras''') is an approach for formally modeling concurrent systems. ''Process'' refers to the behavior of a system. The word ''algebra'' denotes an algebraic approach in talking about behavior, while the word ''calculus'' emphasizes the computational aspect of processes.&lt;br /&gt;
&amp;lt;ref name=&amp;quot;Baeten&amp;quot;&amp;gt;&lt;br /&gt;
J.C.M. Baeten: [https://pure.tue.nl/ws/files/2154050/200402.pdf A brief history of process algebra.], Theoretical Computer Science 335 (2005) 131 – 146&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
There are lots of implementations of this approach and none of them can be pointed to as the primary one. &lt;br /&gt;
&lt;br /&gt;
A process calculus can be characterized by the atomic units of behavior (actions, events) and formers of compound processes (operators, combinators).&lt;br /&gt;
Implementations may include several of both categories and they are often open for extensions.&lt;br /&gt;
&lt;br /&gt;
It is a recurrent pattern in the literature that processes can be viewed in two ways: one can combine component processes and examine the evolution of the resulting process. In this setting component processes may communicate with each other and the compound process may come to a rest without displaying external behavior. A single process can also be examined by placing it into a (not strictly specified) environment which is able to interact with the process. &lt;br /&gt;
&lt;br /&gt;
Pipe-calculus fits into this framework if we make the following observations.&lt;br /&gt;
&lt;br /&gt;
* Prefixes are atomic units of behavior (actions).&lt;br /&gt;
* Prefixes with sequential composition and choice form basic process algebra (BPA). &amp;lt;ref name=&amp;quot;Fokkink&amp;quot;&amp;gt;&lt;br /&gt;
Wan Fokkink: [https://www.cs.vu.nl/~wanf/BOOKS/procalg.pdf Introduction to Process Algebra], Springer-Verlag&lt;br /&gt;
&amp;lt;/ref&amp;gt;&lt;br /&gt;
* The pipe operation can be seen as a restricted, unidirectional parallel composition.&lt;br /&gt;
&lt;br /&gt;
There are also notable differences.&lt;br /&gt;
&lt;br /&gt;
* The most outstanding difference is the lack of channels. Pipe-calculus processes only have a conceptual input and output, however one can simulate channels with synchronisation where atoms stand for channel names. &lt;br /&gt;
* Communication primitives in mainstream process calculi often inseparably unite two conceptual steps: the selection of a communication channel and the act of message sending. For example [[wikipedia:pi-calculus|Π-calculus]] &amp;lt;ref&amp;gt; Joachim Parrow: [https://courses.cs.vt.edu/~cs5204/fall05-kafura/Papers/PICalculus/parrow~2.pdf An Introduction to the π-Calculus], chapter to appear in Handbook of Process Algebra, ed. Bergstra, Ponse and Smolka,&lt;br /&gt;
Elsevier&amp;lt;/ref&amp;gt; defines ''input prefixing'' &amp;lt;math&amp;gt;c\left(x\right).P&amp;lt;/math&amp;gt; and ''output prefixing'' &amp;lt;math&amp;gt;\overline{c} \langle y \rangle.P&amp;lt;/math&amp;gt; to denote receiving a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and sending a name via channel &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; respectively, before proceeding as &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;. Although one can introduce as convention ''synchronization'' where the communicated message is ignored, and ''broadcast'' where a group of processes are receiving messages on the same channel. In pipe-calculus these steps are separated by design.&lt;br /&gt;
* In pipe-calculus there is no counterpart of ''name hiding'' that prevents interference between two groups of processes using the same channel name for communication. Since there is no general, bidirectional parallel composition, we don't need a hiding primitive. The pipe operation naturally restricts communication to a pipeline.&lt;br /&gt;
* In pipe-calculus, if a process fails to synchronize, it is aborted. This is different from the usual implementation where a process that fails to synchronize does not evolve, it &amp;quot;keeps waiting&amp;quot; for a message, opening up the possibility for asynchronous communication.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>KalmanKeri</name></author>
	</entry>
</feed>