Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Singleton check loops on recursive eta record #5823

Closed
oisdk opened this issue Mar 10, 2022 · 3 comments · Fixed by #5844
Closed

Singleton check loops on recursive eta record #5823

oisdk opened this issue Mar 10, 2022 · 3 comments · Fixed by #5844
Assignees
Labels
eta η-expansion of metavariables and unification modulo η records Record declarations, literals, constructors and updates singleton-types Issues related to conversion modulo eta-equality for singleton types type: bug Issues and pull requests about actual bugs
Milestone

Comments

@oisdk
Copy link

oisdk commented Mar 10, 2022

The following code loops in Agda 2.6.2.1:

record Acc {a r} {A : Type a} (R : A  A  Type r) (x : A) : Type (a ℓ⊔ r) where
  inductive; eta-equality
  constructor acc
  field step :  y  R y x  Acc R y
open Acc public

isPropAcc :  {r} {R : A  A  Type r} {x : A}  isProp (Acc R x)
isPropAcc (acc x) (acc y) = cong acc (funExt λ n  funExt λ p  isPropAcc (x n p) (y n p))

It uses a recursive inductive record (the Acc type for well-founded recursion), and tries to prove a property on it by recursing over it.

I am not sure if this behaviour is expected (it goes away if eta-equality is replaced by pattern), but the manual seems to suggest that this code should be safe.

@andreasabel andreasabel added type: bug Issues and pull requests about actual bugs eta η-expansion of metavariables and unification modulo η records Record declarations, literals, constructors and updates labels Mar 10, 2022
@andreasabel
Copy link
Member

Agda loops when trying to check whether Acc R x is a singleton; it unfolds forever:

considering eta-expansion at type
Acc (_R_83 (x = x₄) (y = y₂)) y₃

Is Acc (_R_83 (x = x₄) (y = y₂)) y₃ a singleton record type?
isSingletonRecord' checking telescope  (step₁
                                        : (y₄ : _A_82 (x = x₄) (y = y₂)) →
                                          _R_83 (x = x₄) (y = y₂) y₄ y₃ →
                                          Acc (_R_83 (x = x₄) (y = y₂)) y₄)
Is Acc (_R_83 (x = x₄) (y = y₂)) y₄ a singleton record type?
...

@andreasabel andreasabel self-assigned this Mar 10, 2022
@andreasabel andreasabel added this to the 2.6.2.2 milestone Mar 10, 2022
andreasabel added a commit that referenced this issue Mar 10, 2022
…rd types

Otherwise we might get into infinite unfolding...
@andreasabel
Copy link
Member

Congrats, @oisdk, you found a bug that has been open since Agda 2.5.1.1!
It is fixed on #5824, and now you get the termination error you deserve instead. (Can't recurse on a eta record type!)

@andreasabel andreasabel modified the milestones: 2.6.2.2, 2.6.3 Mar 13, 2022
@andreasabel
Copy link
Member

Here is a MWE that makes Agda loop (since Agda 2.5.1.1, when eta-equality was added):

record Empty : Set where
  inductive; eta-equality
  field out : Empty

test : Empty
test = _

andreasabel added a commit that referenced this issue Mar 22, 2022
…rd types

Otherwise we might get into infinite unfolding...
andreasabel added a commit that referenced this issue Mar 23, 2022
For inductive record types with eta-equality, the check for singleton
type (constructing the unique inhabitant) was looping for
non-terminating records.

As a remedy, the check now keeps a record of already unfolded recursive
record types.  This alone is too restrictive, because "terminating"
record types should always be unfolded (to their field telescope).
The Data.Record module from the standard-library relied on this
feature in order to construct the record signature automatically by
basically just eta-expansion.

To keep Data.Record etc working, this commit also adds a termination
checker for record types.  To this end, a record type

    record R pars : Set where
      field
        f1 : A1
        ...
        fn : An

is considered as a list of definitions

    R pars = A1
    ...
    R pars = An

which are subjected to call extraction and termination checking.

Record types that fail the termination check are remembered as such,
setting

    recTerminates = Just False

in the `Record` `Definition`, but no termination error is reported.
andreasabel added a commit that referenced this issue Mar 23, 2022
For inductive record types with eta-equality, the check for singleton
type (constructing the unique inhabitant) was looping for
non-terminating records.

As a remedy, the check now keeps a record of already unfolded recursive
record types.  This alone is too restrictive, because "terminating"
record types should always be unfolded (to their field telescope).
The Data.Record module from the standard-library relied on this
feature in order to construct the record signature automatically by
basically just eta-expansion.

To keep Data.Record etc working, this commit also adds a termination
checker for record types.  To this end, a record type

    record R pars : Set where
      field
        f1 : A1
        ...
        fn : An

is considered as a list of definitions

    R pars = A1
    ...
    R pars = An

which are subjected to call extraction and termination checking.

Record types that fail the termination check are remembered as such,
setting

    recTerminates = Just False

in the `Record` `Definition`, but no termination error is reported.
@andreasabel andreasabel added the singleton-types Issues related to conversion modulo eta-equality for singleton types label Mar 24, 2022
@andreasabel andreasabel changed the title Loop on eta record Singleton check loops on recursive eta record Oct 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
eta η-expansion of metavariables and unification modulo η records Record declarations, literals, constructors and updates singleton-types Issues related to conversion modulo eta-equality for singleton types type: bug Issues and pull requests about actual bugs
Projects
None yet
2 participants