A bag recursion run against a counter #
The table a body apply is tabulated by evaluates the right side at every
type of the parameter row, those no row of the recursive relation ever
has included, and a bag recursion inside the right side may run forever
there. Inside the table, every bag recursion is therefore bounded: its
rounds carry a counter, the base the least of a list of counters, and
each round moves the counter to its successor, so that the recursion
stops after as many rounds as there are counters, on every instance. As
long as the original recursion settles within that many rounds – which a
restricted recursion over a bounded set of values does
(AggQueryIn.mu_eq_muSum_of_valsIn) – the bounded one computes the same
rows, the counter projected away.
The bounded recursion is Sym.symMuQ; every row of a round carries that
round's counter and the recursion stops after the last one
(Sym.simStep_suf, Sym.simStep_last), and over symbolic rows its slice
under a descriptor is the encoding of the recursion's rows
(Sym.sliceIs_symMu).
Dependency graph
Dependency graph
The successor relation of a list of counters: each counter with the next.
Equations
- Sym.succRel cs = ↑(List.map (fun (ab : Tuple T K × Tuple T K) => Fin.append ab.1 ab.2) (cs.zip cs.tail))
Instances For
Dependency graph
A round of the bounded recursion: the round function on the rows, each output row moved to the successor of its counter.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The bounded recursion as a query #
Dependency graph
The product of two all-regular queries, all-regular.
Equations
- Sym.prodR q₁ q₂ = AggQueryIn.castKind ⋯ (q₁.Prod q₂)
Instances For
Dependency graph
The counters of a round and of the successor agree.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The columns a bounded round keeps: the row's, and the successor's counter.
Equations
- Sym.stepCols i = Fin.addCases (fun (i : Fin N) => Sym.SA.col (Fin.castAdd (K + K) (Fin.castAdd K i))) (fun (z : Fin K) => Sym.SA.col (Fin.natAdd (N + K) (Fin.natAdd K z))) i
Instances For
Dependency graph
A round of the bounded recursion, as a query: the body's rows whose counter has a successor, moved to it.
Equations
- Sym.stepQ s Bq Sq = AggQueryIn.castKind ⋯ (AggQueryIn.Proj (Sym.projSA Sym.stepCols) (AggQueryIn.Sel Sym.ctrEqSP.toGen (Sym.prodR Bq Sq) ⋯))
Instances For
Dependency graph
The bounded recursion: the base paired with the least counter, each round moved to the next counter, the counter projected away.
Equations
- Sym.symMuQ s Q₀ Bq Lq Sq = AggQueryIn.castKind ⋯ (AggQueryIn.Proj (Sym.projSA fun (i : Fin N) => Sym.SA.col (Fin.castAdd K i)) (AggQueryIn.Mu s (Sym.prodR Q₀ Lq) (Sym.stepQ s Bq Sq)))
Instances For
Dependency graph
The rounds of the bounded recursion, round by round #
Every row of a round carries that round's counter, and there are no rows past the last counter, as long as the round function keeps each row's counter.
Dependency graph
The bounded recursion stops after the last counter.
Dependency graph
The symbolic bounded recursion's slices #
The symbolic bounded recursion's slice: the encodings of the recursion's rows, wherever the recursion settles within as many rounds as there are counters and its rounds hold good values.