Changelog for Agda-2.6.20240806
Release notes for Agda version 2.7.0
Highlights
-
Mimer, a re-implementation of the "auto" term synthesizer, replaces Agsy.
-
New syntax
using x ← e
to bind values on the left-hand-side of a function clause. -
Instance search is more performant thanks to a new indexing structure. Additionally, users can now control how instances should be selected in the case multiple candidates exist.
-
User-facing options
--exact-split
,--keep-pattern-variables
, and--postfix-projections
are now on by default.
Installation
-
Agda versioning scheme switches to the Haskell Package Versioning Policy so Agda can be more reliably used as a library. Major releases will now bump the second number in the version tuple: 2.7.0, 2.8.0, 2.9.0, ...
-
When the creation of the Agda library interface files fails during installation, a warning is emitted rather than aborting installation. The absence of these interface files is not a problem if the Agda installation resides in user space; they will be created on the fly then. Yet for system-wide installations in root space or packaging, the interface files should be created. This can be achieved by a manual invocation of Agda on the library source files (i.e., primitive and builtin modules
Agda.*
). (See Issue #7401 and PR #7404.) -
Agda supports GHC versions 8.6.5 to 9.10.1.
Pragmas and options
-
[Breaking] The option
--overlapping-instances
, which allows backtracking during instance search, has been renamed to--backtracking-instance-search
. -
These options are now on by default:
--exact-split
: Warn about clauses that are not definitional equalities.--keep-pattern-variables
: Do not introduce dot patterns in interactive splitting.--postfix-projections
: Print projections and projection patterns in postfix.--save-metas
: Try to not unfold metavariable solutions in interface files.
To revert to the old behavior, use options
--no-...
. -
Option
--rewriting
is now considered infective. This means that if a module has this flag enabled, then all modules importing it must also have that flag enabled. -
New warnings:
-
CoinductiveEtaRecord
if a record is declared bothcoinductive
and havingeta-equality
. Used to be a hard error; now Agda continues, ignoringeta-equality
. -
ConflictingPragmaOptions
if giving both--this
and--that
when--this
implies--no-that
(and analogous for--no-this
implies--that
, etc). -
ConstructorDoesNotFitInData
when a constructor parameter is too big (in the sense of universe level) for the target data type of the constructor. Error warning, used to be a hard error. -
DuplicateRecordDirectives
if e.g. arecord
is declared bothinductive
andcoinductive
, or declaredinductive
twice. -
UselessMacro
when amacro
block does not contain any function definitions. -
WarningProblem
when trying to switch an unknown or non-benign warning with the-W
option. Used to be a hard error.
-
-
Rejected rewrite rules no longer cause a hard error but instead cause an error warning. The following warnings were added to document the various reasons for rejection:
RewriteLHSNotDefinitionOrConstructor
RewriteVariablesNotBoundByLHS
RewriteVariablesBoundMoreThanOnce
RewriteLHSReduces
RewriteHeadSymbolIsProjection
RewriteHeadSymbolIsProjectionLikeFunction
RewriteHeadSymbolIsTypeConstructor
RewriteHeadSymbolContainsMetas
RewriteConstructorParametersNotGeneral
RewriteContainsUnsolvedMetaVariables
RewriteBlockedOnProblems
RewriteRequiresDefinitions
RewriteDoesNotTargetRewriteRelation
RewriteBeforeFunctionDefinition
RewriteBeforeMutualFunctionDefinition
Lossy unification
-
New option
--require-unique-meta-solutions
(turned on by default). Disabling it with--no-require-unique-meta-solutions
allows the type checker to take advantage ofINJECTIVE_FOR_INFERENCE
pragmas (see below). The--lossy-unification
flag implies--no-require-unique-meta-solutions
. -
New pragma
INJECTIVE_FOR_INFERENCE
which treats functions as injective for inferring implicit arguments if--no-require-unique-meta-solutions
is given. The--no-require-unique-meta-solutions
flag needs to be given in the file where the function is used, and not necessarily in the file where it is defined. For example:postulate reverse-≡ : {l l' : List A} → reverse l ≡ reverse l' → reverse l ≡ reverse l' []≡[] : [] ≡ [] []≡[] = reverse-≡ (refl {x = reverse []})
does not work since Agda won't solve
l
andl'
for[]
, even though it knowsreverse l = reverse []
. Ifreverse
is marked as injective with{-# INJECTIVE_FOR_INFERENCE reverse #-}
this example will work.
Syntax
Additions to the Agda syntax.
-
Left-hand side let:
using x ← e
(PR #7078)This new construct can be use in left-hand sides together with
with
andrewrite
to give names to subexpressions. It is the left-hand side counterpart of alet
-binding and supports the same limited form of pattern matching on eta-expandable record values.It can be quite useful when you have a function doing a series of nested
with
s that share some expressions. Something likefun : A → B fun x using z ← e with foo z ... | p with bar z ... | q = r
Here the expression
e
doesn't have to be repeated in the twowith
-expressions.As in a
with
, multiple bindings can be separated by a|
, and variables to the left are in scope in bindings to the right. -
Pattern synonyms can now expose existing instance arguments (PR 7173). Example:
data D : Set where c : {{D}} → D pattern p {{d}} = c {{d}}
This allows us to explicitly bind these argument in a pattern match and supply them explicitly when using the pattern synonym in an expression.
f : D → D f (p {{d = x}}) = p {{d = x}}
We cannot create new instance arguments this way, though. The following is rejected:
data D : Set where c : D → D pattern p {{d}} = c d
Language
Changes to type checker and other components defining the Agda language.
-
Agda now uses discrimination trees to store and look up instance definitions, rather than linearly searching through all instances for a given "class" (PR #7109).
This is a purely internal change, and should not result in any change to which programs are accepted or rejected. However, it significantly improves the performance of instance search, especially for the case of a "type class" indexed by a single type argument. The new lookup procedure should never be slower than the previous implementation.
Reflection
Changes to the meta-programming facilities.
-
[Breaking] Erased constructors are now supported in reflection machinery. Quantity argument was added to
data-cons
. For erased constructors this argument has a value ofquantity-0
, otherwise it'squantity-ω
.defineData
now requires setting quantity for each constructor. -
Add new primitive to run instance search from reflection code:
-- Try to solve open instance constraints. When wrapped in `noConstraints`, -- fails if there are unsolved instance constraints left over that originate -- from the current macro invokation. Outside constraints are still attempted, -- but failure to solve them are ignored by `noConstraints`. solveInstanceConstraints : TC ⊤
-
A new reflection primitive
workOnTypes : TC A → TC A
was added toAgda.Builtin.Reflection
. This runs the given computation at the type level, which enables the use of erased things. In particular, this is needed when working with (dependent) function types with erased arguments. For example, one can get the type of the tuple constructor_,_
(which now takes its type parameters as erased arguments, see above) and unify it with the current goal as follows:macro testM : Term → TC ⊤ testM hole = bindTC (getType (quote _,_)) (λ t → workOnTypes (unify hole t)) typeOfComma = testM
Interaction and emacs mode
-
[Breaking] The Auto command Agsy has been replaced by an entirely new implementation Mimer (PR #6410). This fixes problems where Auto would fail in the presence of language features it did not know about, such as copatterns or anything cubical.
The reimplementation does not support case splitting (
-c
), disproving (-d
) or refining (-r
). -
The Agda input method for Emacs has been extended by several character bindings. The list of changes can be obtained with a git diff on the sources:
git diff v2.6.4.3 v2.7.0 -- src/data/emacs-mode/agda-input.el
API
Highlighting some changes to Agda as a library.
-
New module
Agda.Syntax.Common.KeywordRange
providing typeKwRange
isomorphic toRange
to indicate source positions that just span keywords (PR #7162). The motivation forKwRange
is to distinguish such ranges from ranges for whole subtrees, e.g. in data typeAgda.Syntax.Concrete.Declaration
.API:
module Agda.Syntax.Common.KeywordRange where type KwRange -- From Range to KwRange kwRange :: HasRange a => a -> KwRange -- From KwRange to Range instance HasRange KwRange where getRange :: KwRange -> Range
-
New hook in
Agda.Compiler.ToTreeless
to enable custom pipelines in compiler backends (PR #7273).
List of closed issues
For 2.7.0, the following issues were closed (see bug tracker):
- Issue #2492: Limit the size of terms agsy is allowed to insert
- Issue #2853: Auto does not work well with record types
- Issue #4594: Improve the blocking primitive
- Issue #4777: Interaction between tactics and instance search
- Issue #6101: Agsy gives up when no HIT is present
- Issue #6124: Reflection: cannot reduce type because variable is erased
- Issue #6181: Agda incorrectly reports type error when an identity function is not properly hidden from the termination checker
- Issue #6270: Irrelevance in the type of a record module definition
- Issue #6292: Document interaction between reflection and erasure
- Issue #6335: Error message for non-canonical value when using Show instances is confusing
- Issue #6361: Agsy ignores --postfix-projections
- Issue #6406: Subject reduction problem related to projections with non-erased parameter arguments
- Issue #6433: Add unicode character BALLOT X as \crossmark to Agda input mode
- Issue #6509: Agda seems to be very slow at typechecking records with many fields
- Issue #6584: Case splitting on record renames top-level function
- Issue #6643: Rewrite rules are allowed in implicit mutual blocks
- Issue #6663: Function arguments are nonvariant more often than they should be
- Issue #6667: An internal error occurrs when (mis)using syntax declarations
- Issue #6744: Alias in constructor index foils the forcing analysis
- Issue #6768: auto: not implemented HITs error on non-cubical code
- Issue #6783:
@tactic
does not kick in for lambdas - Issue #6806: Remove
GenericWarning
- Issue #6841: Uncaught pattern violation when using
with...in...
instead of old-school inspect - Issue #6866: User Manual: Make Installation as Easy as Possible
- Issue #6867: Agda rejects identity function on indexed datatype with erased index
- Issue #6919: improving formatting of warnings/errors
- Issue #6943: Making
--exact-split
and--postfix-projections
default? - Issue #6945: Missing warning for non-empty but effectless
private
blocks - Issue #6976: Unexpected failure of instance resolution
- Issue #7017: Document instance projections
- Issue #7058: Unclear specification and correctness of TypeChecking/DeadCode
- Issue #7090: REWRITE rule with confluence, inconsistencies with documentation and error messages
- Issue #7123: Citation.cff
- Issue #7136: Pattern synonyms with named arguments can be defined but not used
- Issue #7146: Misprinted domain-free parameters with cohesion attribute
- Issue #7158: Non-sensical error since 2.5.4 when applying a non-function
- Issue #7167: Underapplied pattern synonyms expand to lambdas with wrong hiding in expressions
- Issue #7170: Confusing error "Unused variable in pattern synonym"
- Issue #7176: Instanceness is lost when expanding absurd pattern in pattern synonym expression
- Issue #7177: No scope info for underscores inserted by pattern synonym expansion
- Issue #7181: Forcing translation prevents reduction within function definition
- Issue #7182:
getDefinition
gives wrong constructor for record from applied parameterised module - Issue #7187: Sort metas produce ill-typed reflected terms when quoted
- Issue #7191:
show
does not respectabstract
/opaque
when normalising a term in a hole - Issue #7192: GHC 9.10
- Issue #7193: Agda always has irrelevant projections
- Issue #7196: Regression when giving instances with visible arguments
- Issue #7202:
ModuleDoesntExport
has imprecise deadcode highlighting - Issue #7208: Importing module with wrong namespace causes internal error instead of user-friendly error.
- Issue #7218: Internal error in opaque block when case splitting when just given extended lambda
- Issue #7219: Only warn about unknown warnings, don't fail hard
- Issue #7227: Save-metas causes OOM during macro execution
- Issue #7236: Expected a hidden argument, but found a visible argument in with-abstraction when using REWRITE
- Issue #7262: Error "This clause has target type ... which is not usable" highlights pattern instead of clause
- Issue #7266: Internal error at Agda/TypeChecking/Substitute.hs:140:33
- Issue #7286: Hard error on
instance
definition with unsolved type - Issue #7301: Agda >=2.6.3 hangs on conflicting record directives
- Issue #7318:
--postfix-projections
do not make use of mixfix syntax - Issue #7326: Internal error on pattern lambda with no clauses
- Issue #7329: wrong type for unnamed record constructor
- Issue #7331: Search for project root crashes when (parent) directory lacks permissions
- Issue #7332: quoteTerm loops on dependent copattern lambda
- Issue #7337: Caching loses reflection-generated pragmas
- Issue #7346: Proof of ⊥ using HIT-indexed type
- Issue #7380: MAlonzo bug:
unreachable code reached
- Issue #7382: Agda 2.7.0-rc1 crashes when run twice, probably serialization issue
- Issue #7401: Cabal 3.12.1.0 install failure for lib:Agda - dist/build/agda/agda does not exist
These (relevant) pull requests were merged for 2.7.0:
- PR #6410: Mimer: a drop-in replacement for Agsy
- PR #6569: Do final checks before freezing metas
- PR #6570: Coerce
unquote
applications - PR #6640: Add
INJECTIVE_FOR_INFERENCE
pragma - PR #6674: Testcase for fixed #6542
- PR #6769: Various symbol additions to agda-input
- PR #6870: [ fix #6867 ] Only consider arguments with @0 for forcing if --erasure is on
- PR #6978: [ fix #6976 ] Add constraint for resolving the head of an instance
- PR #7055: Unspine system projections when they have display forms
- PR #7071: Eta-expand mismatched cubical primitives
- PR #7078: Left-hand side
let
- PR #7109: Discrimination trees for instance search
- PR #7115: Flake improvements
- PR #7119: Split GenericWarning into individual warnings
- PR #7121: Update installation.rst
- PR #7138: Fix #7136: proper error when pattern definition has unsupported arguments
- PR #7142: Fix #6783: error for @tactic on lambda
- PR #7144: Add reference to Cornelis in the documentation
- PR #7147: Fix #7146: printing of cohesion and lock attributes
- PR #7149: Fix mutual information not being set properly by the positivity checker
- PR #7155: Fix #6866: User Manual: Make Installation as Easy as Possible
- PR #7159: Fix #7158: Application: check for sufficient arity before checking target
- PR #7160: Fix #6667: case not
__IMPOSSIBLE__
for nullary syntax - PR #7161: Fix #6945: warn about useless private even in absense of nice decls
- PR #7162: Blocks in Concrete syntax: store Range of block keyword
- PR #7168: Fix #7167: type checking underapplied pattern synonyms
- PR #7169: Trigger and improve error UnusedVariableInPatternSynonym
- PR #7173: Part of #2829: Allow instance arguments in pattern synonyms that are such in the pattern already
- PR #7179: Fix #7177: only setScope when scope is not null
- PR #7180: Use compareAs for assignE even in compareAtom
- PR #7183: Instance overlap pragmas
- PR #7185: Fix #7176: turn absurd pattern in instance position to instance meta
- PR #7197: Re. #7196: Only prune instances in serialised iface
- PR #7203: Fix incorrectly quoted sorts
- PR #7204: Fix #7202: ModuleDoesntExport: only highlight missing names
- PR #7209: Fix #7208: restore missing check for OverlappingProjects
- PR #7210: Fix range for deprecated module import warning when applied
- PR #7211: Fix #7181: Allow matching to continue when stuck on lazy pattern
- PR #7222: Fix #7219: only warn about problems with warning options
- PR #7231: Instantiate terms before traversing them in tcExtendContext
- PR #7237: Fix #7236: use context rather than telescope for lambda-bound variables in rewrite patterns
- PR #7238: Build with GHC 9.10
- PR #7241: Drop time-compat dependency and Stack LTS for GHC 8.6
- PR #7243: re. 7218: Saturate opaque blocks after Give commands
- PR #7248: Overhaul dead code elimination, make --save-metas the default
- PR #7249: docs/installation: point new wiki
- PR #7251: re. 7250: copy instanceinfo
- PR #7252: Fix #7193: persistently remember what is a projection
- PR #7260: Reflection primitive to solve instances
- PR #7273: ToTreeless: allow backends to define custom pipelines
- PR #7274: #7182: copied records should refer to the copied constructor and fields
- PR #7276: #7191: respect abstract mode when using show function
- PR #7283: agdaLatex documentation
- PR #7292: New error warning
ConstructorDoesNotFitInData
instead of hard error. - PR #7298: Remove fiddly attempt at instance postponement
- PR #7300: New deadcode warning CoinductiveEtaRecord instead of GenericError
- PR #7302: Fix #7301 (loop in parser): move verifyRecordDirectives to scope checker
- PR #7305: Fix #7286: don't fail hard when there are instances with unresolved types
- PR #7307: fix #7017: document instance projections
- PR #7310: Add
workOnTypes
reflection primitive - PR #7311: [ #6406 ] Add test cases from discussion on this issue
- PR #7313: Update universe-levels.lagda.rst
- PR #7314: Add constructors for custom backend warning/errors
- PR #7315: same shadowing logic for record patterns as for constructor patterns in absToCon
- PR #7316: add \crossmark to emacs input mode
- PR #7317: Don't mark eta unit records as irrelevant
- PR #7319: Make --postfix-projections the default
- PR #7320: Turn on --exact-split by default
- PR #7322: Expose constructor erasure in reflection interface
- PR #7325: add CSS rule for macro names
- PR #7327: proper error instead of impossible for clauseless pat-lam
- PR #7330: [#7329] Correct module name in module applications
- PR #7333: [#7332] don't loop when quoting dependent copattern lambdas
- PR #7334: Fix #7331: handle permission error in search for project file
- PR #7336: Remove duplicate imports and pragmas in MAlonzo
- PR #7338: (#7337) foreign code needs to go in post-scope state
- PR #7343: Turn illegal rewrite rules into an error warning
- PR #7347: [ fix #7266 ] Check that constructor names match before projecting in
matchPattern
- PR #7349: Fix #7346 by not considering HIT-constructor arguments forced
- PR #7350: Fix #6744 by reducing during forcing analysis.
- PR #7352: Fix issue 7262: Range of the lhs modality check
- PR #7353: Update installation docs (e.g. re #7163: document installation problems with
executable-dynamic
) - PR #7355: Make
--keep-pattern-variables
the default - PR #7356: Add --save-metas default to CHANGELOG
- PR #7358: [ doc ] Document
--termination-depth
in user manual - PR #7359: Fix #7354 by making types of live metas live in DeadCode
- PR #7360: Fix for issue #6841 and related changes
- PR #7362: Fix #6919: separate warnings by empty line
- PR #7364: Resolve instance overlap for irrelevant metas
- PR #7367: Minor fixes to instance overlap + constraint postponement
- PR #7383: Fix #7382: make all module param sections live in DeadCode
- PR #7386: Testcase for #7382 (completes PR #7383)
- PR #7404: Fix #7401: do not fail hard in Setup.hs if library interface files cannot be built
- PR #7410: Fixup #7404 and test agdai-generation in cabal-install workflow
- PR #7419: #7380: add clauses to generalizedTel projections
- PR #7423: Fixup #7265: restore passing arguments from goal to Mimer