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

Termination checking prefers data to record #7206

Closed
lawcho opened this issue Mar 27, 2024 · 4 comments
Closed

Termination checking prefers data to record #7206

lawcho opened this issue Mar 27, 2024 · 4 comments
Labels
data Inductive data definitions eta η-expansion of metavariables and unification modulo η records Record declarations, literals, constructors and updates termination Issues relating to the termination checker type: question User questions (not in changelog)
Milestone

Comments

@lawcho
Copy link
Contributor

lawcho commented Mar 27, 2024

foldSS passes when data is used, but not when record is used:

-- Fails syntax-based termination checking
record SillyStream (A : Set) : Set where
  inductive; eta-equality; constructor _∷_
  field head : A
  field tail : SillyStream A

-- -- Passes syntax-based termination checking
-- data SillyStream (A : Set) : Set where
--   _∷_
--     : (head : A)
--     → SillyStream A
--     → SillyStream A

foldSS : {A r : Set}  (A  r  r)  SillyStream A  r
foldSS f (head ∷ tail)  = f head (foldSS f tail)

I expected syntax-based termination to spot the structural recursion either way.

Agda Versions tested

@lawcho lawcho added termination Issues relating to the termination checker records Record declarations, literals, constructors and updates data Inductive data definitions labels Mar 27, 2024
@andreasabel
Copy link
Member

It should work if you put no-eta-equality.
With eta, foldSS is not terminating due to the record pattern translation which turns this into

foldSS f s = f (head s) (foldSS f (tail s))

@andreasabel andreasabel added eta η-expansion of metavariables and unification modulo η type: question User questions (not in changelog) labels Mar 27, 2024
@lawcho
Copy link
Contributor Author

lawcho commented Mar 27, 2024

This passes:

record SillyStream (A : Set) : Set where
  inductive; pattern; constructor _∷_
  field head : A
  field tail : SillyStream A

foldSS : {A r : Set}  (A  r  r)  SillyStream A  r
foldSS f (head ∷ tail)  = f head (foldSS f tail)

@andreasabel
Copy link
Member

Yes, because eta is off. This gives an error:

...
module _ (A : Set) (s : SillyStream A) where

  eta : s ≡ head s ∷ tail s
  eta = refl

@lawcho
Copy link
Contributor Author

lawcho commented Mar 27, 2024

It seems like pattern is enough to get data-style checking of a record.

I don't think a doc update is required, since the pattern keyword is discoverable via Agda's error message:

/tmp/tmp.O6kGsXwZPr/tmp.agda:8,11-22
Pattern matching on no-eta record type SillyStream
(defined at /tmp/tmp.O6kGsXwZPr/tmp.agda:2,8-19) is not allowed
(to activate, add declaration `pattern` to record definition)
when checking that the pattern head ∷ tail has type SillyStream A

which arises when I give a naive translation of the data type:

record SillyStream (A : Set) : Set where
  inductive; constructor _∷_
  field head : A
  field tail : SillyStream A

(Agda version 422b932 of master)

@lawcho lawcho closed this as completed Mar 27, 2024
@andreasabel andreasabel added this to the never milestone Mar 27, 2024
knisht added a commit to knisht/agda that referenced this issue Mar 29, 2024
knisht added a commit to knisht/agda that referenced this issue Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data Inductive data definitions eta η-expansion of metavariables and unification modulo η records Record declarations, literals, constructors and updates termination Issues relating to the termination checker type: question User questions (not in changelog)
Projects
None yet
Development

No branches or pull requests

2 participants