The calf language is a cost-aware logical framework for studying quantitative aspects of functional programs.
This repository contains the Agda implementation of calf, as well as some case studies of varying complexity.
The source code may be viewed interactively with (semantic) syntax highlighting in the browser using the HTML files in the ./html directory.
These files were generated by running:
agda --html --html-dir=html src/index.agdaYou may want to start by opening html/index.html.
To view a specific module M, open html/M.html in a web browser.
For example, open html/Examples.Sorting.Parallel.html to view the module Examples.Sorting.Parallel.
This implementation of calf has been tested using:
- Agda v2.6.3, with
agda-stdlibv2.0 experimental
Installation instructions may be found in INSTALL.md.
calf is parameterized by a cost monoid (ℂ, +, zero, ≤).
The formal definition, CostMonoid, is given in Algebra.Cost.
The definition of a parallel cost monoid (ℂ, ⊕, 𝟘, ⊗, 𝟙, ≤) is given, as well, as ParCostMonoid.
Some common cost monoids and parallel cost monoids are given in Algebra.Cost.Instances; for example, ℕ-CostMonoid simply tracks sequential cost.
Note that every ParCostMonoid induces a CostMonoid via the additive substructure (ℂ, ⊕, 𝟘, ≤).
The language itself is implemented via the following files, which are given in a dependency-respecting order.
The following modules are not parameterized:
Calf.Preludecontains commonly-used definitions.Calf.CBPVdefines the basic dependent Call-By-Push-Value (CBPV) language, using Agdapostulates and rewrite rules.Calf.Directeddefines a preorder on each type, per the developments in decalf.Calf.Phasedefines the phase distinction of extension and intension:Calf.Phase.Corepostulates a proposition,ext, for the extensional phase.Calf.Phase.Opendefines the open/extensional modality◯forext.Calf.Phase.Closeddefines the closed/intensional modality●forext.Calf.Phase.Directedpostulates the decalf law that underext, inequality coincides with equality.Calf.Phase.Noninterferencecontains theorems related to the phase distinction/noninterference.
The following modules are parameterized by a CostMonoid:
Calf.Stepdefines the computational effectstepand the associated coherence laws via rewrite rules.
The following modules are parameterized by a ParCostMonoid:
Calf.Paralleldefines the parallel execution operation_∥_whose cost structure is given by the product operation of aParCostMonoid(i.e.,_⊗_).
In src/Calf/Data, we provide commonly-used data types.
The following modules are not parameterized and simply internalize the associated Agda types via the meta⁺ primitive:
Calf.Data.BoolCalf.Data.EqualityCalf.Data.ListCalf.Data.MaybeCalf.Data.NatCalf.Data.ProductCalf.Data.Sum
The following modules define custom, calf-specific data types for cost analysis and are parameterized by a CostMonoid:
Calf.Data.IsBoundedGdefines a generalized notion of cost bound,IsBoundedG, where a bound is a program of typeF unit. Additionally, it provides lemmas for proving the boundedness of common forms of computations.Calf.Data.IsBoundedinstantiatesIsBoundedGfor cost bounds of the formstep (F unit) c (ret triv).Calf.Data.BoundedFunctiondefines cost-bounded functions usingIsBounded.Calf.Data.BigOgives a definition of "big-O" asymptotic bounds viaIsBounded. In particular, an element of the typegiven A measured-via size , f ∈𝓞(g)(i.e., "given an input of typeAand a size measuresizeonA,fis in𝓞(g)) is a lower bound on input sizesn'and a constant multiplierkalong with a proofhthat for all inputsxwithn' ≤ size x,f xis bounded bykmultiples ofg (size x), denotedn' ≤n⇒f[n]≤ k g[n]via h.
We provide a variety of case studies in src/Examples.
module Easy- Definition of the program
idthat trivially returns its input. - Definition of the cost bound program
id/bound, which here is the same asid. - Theorem
id/is-boundedshowing thatidis bounded byid/bound. - Theorem
id/correctstating the extensional correctness ofidas a corollary ofid/is-bounded. - Theorem
id/asymptotic : given nat measured-via (λ n → n) , id ∈𝓞(λ n → 0)stating thatidis in𝓞(0).
- Definition of the program
module Hard- Definition of the program
idthat reconstructs its input via induction. - Definition of the cost bound program
id/bound, which incursncost before returningn. - Theorem
id/is-boundedshowing thatidis bounded byid/bound. - Theorem
id/correctstating the extensional correctness ofidas a corollary ofid/is-bounded. - Theorem
id/asymptotic : given nat measured-via (λ n → n) , id ∈𝓞(λ n → n)stating thatidis in𝓞(n), wherenis the input number.
- Definition of the program
- A proof that
Easy.idandHard.idare extensionally equivalent,easy≡hard : ◯ (Easy.id ≡ Hard.id), as a corollary of theid/correctproofs.
- Definition of the program
sumthat sums the elements of a tree, incurring unit cost when performing each addition operation. At each node, the recursive calls are computed in parallel. - Definition of the cost bound program
sum/bound, which incurssize t , depth tcost before returning the sum of the tree via a value-level function. - Theorem
sum/has-coststating thatsumandsum/boundare equivalent. - Theorem
sum/is-boundedstating that the cost ofsum tis bounded bysum/bound, as a corollary ofsum/has-cost.
module Slow- Definition of the program
exp₂that computes the exponentation of two by its input by performing two identical recursive calls. Since two identical recursive calls are made in parallel, the work is exponential, but the span is still linear. - Definition of the cost bound program
exp₂/bound, incurring2 ^ n - 1 , ncost before returning result2 ^ n. - Theorem
exp₂/is-boundedshowing thatexp₂is bounded byexp₂/bound. - Theorem
exp₂/correctstating the extensional correctness ofexp₂as a corollary ofexp₂/is-bounded. - Theorem
exp₂/asymptotic : given nat measured-via (λ n → n) , exp₂ ∈𝓞(λ n → 2 ^ n , n)stating thatexp₂is in𝓞(2 ^ n , n).
- Definition of the program
module Fast- Definition of the program
exp₂which computes the exponentation of two by its input via a standard recursive algorithm. - Definition of the cost bound program
exp₂/bound, incurringn , ncost before returning result2 ^ n. - Theorem
exp₂/is-boundedshowing thatexp₂is bounded byexp₂/bound. - Theorem
exp₂/correctstating the extensional correctness ofexp₂as a corollary ofexp₂/is-bounded. - Theorem
exp₂/asymptotic : given nat measured-via (λ n → n) , exp₂ ∈𝓞(λ n → n , n)stating thatexp₂is in𝓞(n , n).
- Definition of the program
- A proof that
Slow.exp₂andFast.exp₂are extensionally equivalent,slow≡fast : ◯ (Slow.exp₂ ≡ Fast.exp₂).
First, we develop a common collection of definitions and theorems used in both sequential and parallel sorting.
Examples.Sorting.Comparable- Record
Comparabledescribing the requirements for a type to be comparable, includingh-cost, a hypothesis that each comparison is bounded by unit cost. This serves as the cost model for sorting.
- Record
Examples.Sorting.Core- Predicates for correctness of sorting, based on
Sortedand the permutation relation↭fromagda-stdlib. The predicateIsSort sortstates thatsortis a correct sorting algorithm. - Theorem
IsSort⇒≡, which states that any two correct sorting algorithms are extensionally equivalent.
- Predicates for correctness of sorting, based on
Here, we use cost monoid ℕ-CostMonoid, tracking the total number of sequential steps incurred.
Examples.Sorting.Sequential.InsertionSort- Definition of the program
sortimplementing insertion sort. - Theorem
sort/correct : IsSort sortverifying the correctness ofsort. - Theorem
sort≤sort/cost/closedstating that the cost ofsort lis bounded bysort/cost/closed l = length l ². - Theorem
sort/asymptotic : given (list A) measured-via length , sort ∈𝓞(λ n → n ²)stating thatsortis in𝓞(n ²), wherenis the length of the input list.
- Definition of the program
Examples.Sorting.Sequential.MergeSortExamples.Sorting.Sequential.MergeSort.Split- Definition of the program
split, which splits a list in halves. - Theorem
split/correctverifying correctness properties ofsplit. - Theorem
split≤split/coststating that the cost ofsplit lis bounded byzero, since splitting a list into halves requires no comparisons.
- Definition of the program
Examples.Sorting.Sequential.MergeSort.Merge- Definition of the program
merge, which merges a pair of sorted lists. - Theorem
merge/correctverifying correctness properties ofmerge. - Theorem
merge≤merge/cost/closedstating that the cost ofmerge (l₁ , l₂)is bounded bylength l₁ + length l₂.
- Definition of the program
- Definition of the program
sortimplementing merge sort. - Theorem
sort/correct : IsSort sortverifying the correctness ofsort. - Theorem
sort≤sort/cost/closedstating that the cost ofsort lis bounded bysort/cost/closed l = ⌈log₂ length l ⌉ * length l. - Theorem
sort/asymptotic : given (list A) measured-via length , sort ∈𝓞(λ n → n * ⌈log₂ n ⌉)stating thatsortis in𝓞(n * ⌈log₂ n ⌉), wherenis the length of the input list.
Theorem isort≡msort : ◯ (ISort.sort ≡ MSort.sort) states that InsertionSort.sort and MergeSort.sort are extensionally equivalent.
Amortized data structures, via coinduction.
Examples.Amortized.Simpleprovides an amortized implementation of a simple amortized stream abstract data type.Examples.Amortized.Queueprovides an implementation of amortized queues.Examples.Amortized.DynamicArrayprovides an implementation of dynamically-growing arrays.
The examples introduced in decalf are included in Examples.Decalf.
We implement and analyze the basic double example.
We introduce the branch and fail primitives for nondeterminism and give the corresponding examples.
module QuickSortincludes the nondeterministic quicksort algorithm using primitives fromExamples.Sorting.Sequential.Core.module Lookupincludes the list lookup function that fails on out-of-bounds indices.module Pervasiveincludes a simple example of pervasive (non-benign) nondeterminism.
We introduce the probabilistic flip primitive and give the corresponding example, showing how the cost of sublist is bounded by the binomial distribution.
We introduce the get and set primitives for global state and show a simple imperative program whose cost bound involves get and set.
We define the twice and map higher-order functions and analyze them under assumptions about their input costs.