This is the Agda implementation for Generic Recursive Lens Combinators and Their Calculation Laws. We use Agda 2.6.2 and agda-stdlib
1.7.
Main constructions:
Lens.agda
: Formalization of lenses (without contracts), provided for comparisonCLens.agda
: contract lenses without using containers
Fixpoint.agda
: fixpoint "μF = F μF
" and useful lemmas
Note: We had to turn off the positivity checker for theμ
type, but it should be safe since all functors we passed to theμ
type are indeed strictly positive (polynomial). InCLens2
/Fixpoint2
, we prove essentially the same results using container-based fixpoints, which completely solves the positivity problem. This version is still provided here because it is arguably easier to comprehend.CLens2.agda
: contract lenses based on containers
Fixpoint2.agda
: fixpoint and lemmas based on containers
As is said above, this version solves the positivity problem.NContainer.agda
: formalization for N-ary containers
NZip.agda
:clift
,fzip
, and related properties based onNContainer
Examples:
example/Tree.agda
: a binary tree. This example shows how accumulations should work on trees.example/Tree2.agda
: a binary tree defined with containers:- We provided definitions of
clift
andfzip
- We defined a bidirectional
F
-algebrabmaxAlg
- We apply the
bFold
combinator withbmaxAlg
to getbmaximum
- We run the
bmaximum
and show the results
- We provided definitions of
Supportive utilities:
Show.agda
: basic pretty-printing supportIntOmega.agda
: integer arithmetic extended to properly handle infinitiesUtils.agda
: some common imports are gathered here
Note: we postulate functional extensionality here. This is the only axiom we assume, and this is safe because (according to PLFA):
Postulating extensionality does not lead to difficulties, as it is known to be consistent with the theory that underlies Agda.
The output of the two examples is provided as follows for your convenience. One should be able to produce the exact same output.
- This is the original tree:
+-3 +-+-1 | +-leaf | `-+-4 | +-leaf | `-leaf `-leaf
- The result of
paths
:+-@tag: [(branch 3 _ _)] +-@val: 3 +-+-@tag: [(branch 3 _ _),(branch 1 _ _)] | +-@val: 1 | +-leaf: @tag: [(branch 3 _ _),(branch 1 _ _),leaf] | `-+-@tag: [(branch 3 _ _),(branch 1 _ _),(branch 4 _ _)] | +-@val: 4 | +-leaf: @tag: [(branch 3 _ _),(branch 1 _ _),(branch 4 _ _),leaf] | `-leaf: @tag: [(branch 3 _ _),(branch 1 _ _),(branch 4 _ _),leaf] `-leaf: @tag: [(branch 3 _ _),leaf]
- The result of
subtrees
:+-@tag: (branch 3 (branch 1 leaf (branch 4 leaf leaf)) leaf) +-@val: 3 +-+-@tag: (branch 1 leaf (branch 4 leaf leaf)) | +-@val: 1 | +-leaf: @tag: leaf | `-+-@tag: (branch 4 leaf leaf) | +-@val: 4 | +-leaf: @tag: leaf | `-leaf: @tag: leaf `-leaf: @tag: leaf
- First part of output is the same as
example/Tree.agda
. - original tree:
Note the
+-3 +-+-1 | +-leaf | `-+-4 | +-leaf | `-leaf `-+-5 +-+-13 | +-+--2 | | +-leaf | | `-leaf | `-leaf `-+-9 +-leaf `-leaf
+--2
should be interpreted as+-(-2)
(the value at that node is-2
). get bmaximum
: 13put bmaximum 2
:+-2 +-+-1 | +-leaf | `-+-2 | +-leaf | `-leaf `-+-2 +-+-2 | +-+--2 | | +-leaf | | `-leaf | `-leaf `-+-2 +-leaf `-leaf
put bmaximum 7
:+-3 +-+-1 | +-leaf | `-+-4 | +-leaf | `-leaf `-+-5 +-+-7 | +-+--2 | | +-leaf | | `-leaf | `-leaf `-+-7 +-leaf `-leaf