anchor.diff:  
   === Problem
   
  +In this CIP we assume the following baseline semantics as a given and well-defined.
  +
  +We also assume following driving table in examples:
  +
  +.Example driving table
  +|===
  +|a|b|c
  +
  +|1|2|3
  +|1|3|4
  +|2|3|5
  +|===
  +
  +==== Baseline aggregation
  +
   Cypher allows grouping and aggregating (form here on just referred to as _aggregation_) the driving table in the WITH and in the RETURN clause.
   
   Formally, the aggregation of a driving table _D_ can be described formally as
  -pass:q[γ<sub>_K_, _A_</sub>(D)] where
  -
  -* _K_ is a (possibly empty) set of grouping keys _k_ and every _k_ is a variable in the driving table _D_, and
  -* _A_ is a non-empty set of aggregation functions _agg_(_x_)_ where _x_ being a variable in the driving table _D_
  +pass:q[γ<sub>_K_, _A_</sub>(_D_)] where
  +
  +* _K_ is a (possibly empty) set of pairs (_k_, _al_) where
  +** _k_ is a variable -- called a _grouping key_ -- in the driving table _D_,
  +** _al_ is variable name -- also called an _alias_ -- that different from all other aliases _x_ with (·, _x_) ∈ _K_., and
  +* _A_ is a non-empty set of triple (_agg_, _x_, _al_) where
  +** _agg_ is an aggregation function and
  +** _x_ is a variable in the driving table _D_
  +** _al_ is variable name -- also called an _alias_ -- that different from all other aliases _x_ with (·, ·, _x_) ∈ _A_ or _x_ with (·, _x_) ∈ _K_.
  +
  +Assuming _K_ = {(_k_~1~, _ka_~1~), (_k_~2~, _ka_~1~), ..., (_k~N~_, _ka~N~_)} and _A_ = {(_agg_~1~, _x_~1~, _al_~1~), (_agg_~2~, _x_~2~, _al_~2~), ..., (_agg~M~_, _x~M~_, _al~M~_)}, the Cypher equivalent of pass:q[γ<sub>_K_, _A_</sub>(_D_)] is
  +
  +[source, cypher, subs="quotes"]
  +----
  +WITH _k_~1~ AS _ka_~1~, _k_~2~ AS _ka_~2~, ..., _k~N~_ AS _ka~N~_,
  +     _agg_~1~(_x_~1~) AS _al_~1~, _agg_~2~(_x_~2~) AS _al_~2~, ..., _agg~M~_(_x~M~_) AS _al~M~_
  +----
  +
  +and
  +
  +[source, cypher, subs="quotes"]
  +----
  +RETURN _k_~1~ AS _k_~1~, _k_~2~ AS _k_~2~, ..., _k~N~_ AS _k~N~_,
  +       _agg_~1~(_x_~1~) AS _al_~1~, _agg_~2~(_x_~2~) AS _al_~2~, ..., _agg~M~_(_x~M~_) AS _al~M~_
  +----
  +
  +Accordingly
  +
  +.[[Q1]]Q1
  +[source, cypher]
  +----
  +RETURN a AS a, SUM(c) AS sumC
  +----
  +
  +Grouped the driving table by `a` and computes the sum of all `c` as `sumC` for each group, so that result is:
  +
  +.Result Q1
  +|===
  +|a|sumC
  +
  +|1|7
  +|2|5
  +|===
  +
  +==== Baseline projection
   
   The WITH and the RETURN clause also allow projecting the driving table including the computation of new columns (in database theory, this is called extended projection).
   
  -The projection of a driving table _D_ can be described formally as pass:q[π<sub>_P_</sub>(D)] where
  -
  -* _P_ is a nonempty set of pair _(ex, al)_ where
  +The projection of a driving table _D_ can be described formally as π__~P~__(_D_) where
  +
  +* _P_ is a nonempty set of pairs (_ex_, _al_) where
   ** _ex_ is a tree of operations of the expression sub-language where each of the leaves is either
   *** a constant (such as a value literal or a label),
   *** a parameter, or
   *** a variable in the driving table _D_; and
  -** _al_ is variable name -- also called in _alias_ in this context -- that different from all other variables _x_ with (·, _x_) ∈ _P_.
  -
  -The WITH and the RETURN clauses also allow renaming, ordering and truncating the driving table, but let's ignore these aspects for now.
  -
  -The WITH and the RETURN clause denoted the parameters for projection (_P_) and aggregation (_K_ and _A_) with a single nonempty list _L_ of https://raw.githack.com/openCypher/openCypher/master/tools/grammar-production-links/grammarLink.html?p=ProjectionItem[<ProjectionItem>] `_ex_ AS _al_` where _ex_ is an expression and _al_ is an alias.
  -The expression of an <ProjectionItem> is allowed to contain aggregation functions.
  -Consequently, the semantics of both clause has to specify how _P_, _K_, and _A_ are defined for a given _L_.
  -
  -It has been documented on multiple occasions (e.g. cf. http://opencypher.org/articles/2017/07/27/ocig1-aggregations-article/[First oCIG Meeting]) the existing semantics or Cypher is imprecise how _P_, _K_, and _A_ are defined for a given _L_.
  -This proposal provides a precise semantics.
  -
  -=== Analysis
  -
  -Consider a driving table
  -
  -.Example driving table
  -|===
  -|a|b|c
  -
  -|1|2|3
  -|1|3|4
  -|2|3|5
  -|===
  -
  -and the RETURN clause
  -
  -.Q1
  -[source, cypher]
  -----
  -RETURN a AS a, SUM(c) AS sumC
  -----
  -
  -Intuitively, it seems clear that the result should be grouped by `a` and the sum of all `c` should be computed as `sumC` for each group, so that result would be:
  -
  -.Result Q1
  -|===
  -|a|sumC
  -
  -|1|7
  -|2|5
  -|===
  -
  -The RETURN clause
  -
  -.Q2
  -[source, cypher]
  -----
  -RETURN a AS a, SUM(b*c) AS sumBC
  -----
  -
  -is intuitively clear in the same way.
  -The result should be grouped by `a` and the sum of all products of `b` and `c` should be computed as `sumBC` for each group, so that result would be:
  +** _al_ is an _alias_ that different from all other aliases _x_ with (·, _x_) ∈ _P_.
  +
  +Assuming _P_ = {(_ex_~1~, _al_~1~), (_ex_~2~, _al_~2~), ..., (_ex~N~_, _al~N~_)}, the Cypher equivalent of π__~P~__(_D_) is
  +
  +[source, cypher, subs="quotes"]
  +----
  +WITH _ex_~1~ AS _al_~1~, _ex_~2~ AS _al_~2~, ..., _ex~N~_ AS _al~N~_
  +----
  +
  +and
  +
  +[source, cypher, subs="quotes"]
  +----
  +RETURN _ex_~1~ AS _al_~1~, _ex_~2~ AS _al_~2~, ..., _ex~N~_ AS _al~N~_
  +----
  +
  +Accordingly, the RETURN clause
  +
  +.[[Q2]]Q2
  +[source, cypher]
  +----
  +RETURN b-a AS x, b*c AS y
  +----
  +
  +projects each row in the driving table to `b` minus `a` (as `x`) and the product of `b` and `c` (as `y`), so that result is:
   
   .Result Q2
   |===
  -|a|sumBC
  -
  -|1|18
  -|2|15
  -|===
  -
  -Similarly, the RETURN clause
  -
  -.Q3
  +|x|y
  +
  +|1|6
  +|2|12
  +|1|15
  +|===
  +
  +The WITH and the RETURN clauses also allow ordering and truncating the driving table, but let's ignore these aspects in this CIP.
  +
  +==== Beyond baseline semantics -- simple rewrite semantics
  +
  +Cypher's WITH and the RETURN are syntactically more flexible when the two baseline semantics. In particular, they allow mixing aggregation and projection rather freely.
  +Specifically, the WITH and the RETURN clause denoted the parameters for projection (_P_) and aggregation (_K_ and _A_) with a single nonempty set _L_ of https://raw.githack.com/openCypher/openCypher/master/tools/grammar-production-links/grammarLink.html?p=ProjectionItem[<ProjectionItem>]s `_ex_ AS _al_` where
  +
  +* _ex_ is an expression that is allowed to contain aggregation functions and
  +* _al_ is an alias.
  +
  +For instance, the RETURN clause
  +
  +.[[Q3]]Q3
   [source, cypher]
   ----
   RETURN b-a AS x, SUM(b*c) AS sumBC
   ----
   
  -should produce a result that is grouped by `b` minus `a` (as `x`) and the sum of all products of `b` and `c` should be computed as `sumBC` for each group, so that result would be:
  +should produce a result that is grouped by `b` minus `a` (as `x`) and the sum of all products of `b` and `c` should be computed as `sumBC` for each group, so that result is:
   
   .Result Q3
   |===
  
positive.code: RETURN x AS x, SUM(sumBC) AS sumBC
  ----
  
  While this solution works nicely for the considered examples, it is limited.
  Specifically, it only supports aggregation function in expressions of the form `_agg_(_ex_)`.
  
  Cypher, however, also allows aggregation functions in expressions of the form, such as
  
  * `_ex1_ + _agg_(_ex2_)`
  * `_agg_(_ex2_) + _ex1_`
  * `_agg1_(_ex2_) + _ex1_ * _agg1_(_ex3_)`
  
  However, such expressions may still be sensible and useful.
  
  Consider the RETURN clause
  
  .Q4
  [source, cypher]
  ----
  RETURN a AS a, (a + SUM(b*c) - MIN(c)) * 2 AS agg
  
negative.code: RETURN AGGR(_L_)
  ----
  
  Analogously, the semantics of `WITH _L_` can be defined as effectively equivalent to
  
  [source, cypher, subs="quotes"]
  ----
  