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

TBT: Bug in size preservation regarding local definitions #7271

Open
andreasabel opened this issue May 15, 2024 · 4 comments
Open

TBT: Bug in size preservation regarding local definitions #7271

andreasabel opened this issue May 15, 2024 · 4 comments
Labels
false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) maculata Issue with a so far unreleased feature (not in changelog) type: bug Issues and pull requests about actual bugs type-based-termination Concerning `--type-based-termination`
Milestone

Comments

@andreasabel
Copy link
Member

TBT accepts a non-productive definition, which we can exploit to make the Agda loop:

{-# OPTIONS --type-based-termination #-}
{-# OPTIONS --size-preservation #-} -- default

-- {-# OPTIONS -v term.tbt:50 #-}

record U : Set where
  coinductive
  field force : U
open U

-- This is not size-preserving, but classified as such:
id : U  U
id u = u' .force where u' = u

-- This should not be accepted:
u : U
u .force = id u

open import Agda.Builtin.Equality

-- Type checker loops:
diverge : u .force ≡ u .force
diverge = refl

ATTN: @knisht

@andreasabel andreasabel added type: bug Issues and pull requests about actual bugs type-based-termination Concerning `--type-based-termination` labels May 15, 2024
@andreasabel andreasabel added this to the 2.7.0 milestone May 15, 2024
@andreasabel
Copy link
Member Author

andreasabel commented May 15, 2024

This exploit also works for inductive types:

open import Agda.Builtin.Nat

f : Nat  Nat
f x = x' where x' = suc (suc x)

diverge : Nat  Nat
diverge zero = zero
diverge (suc n) = diverge (f n)

Accepted by TBT.

@andreasabel andreasabel added false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) maculata Issue with a so far unreleased feature (not in changelog) labels May 15, 2024
@andreasabel
Copy link
Member Author

andreasabel commented May 15, 2024

And BOOM!

I did finally manage to show the current size-preservation analysis inconsistent:

{-# OPTIONS --type-based-termination #-}

data  : Set where

record _×_ (A B : Set) : Set where
  field
    fst : A
    snd : B
open _×_

record U : Set where
  coinductive; constructor delay
  field force : U × ⊥
open U

f : U  U × ⊥
f u = u' .force where u' = u

u : U
u .force = f u

absurd : ⊥
absurd = u .force .snd

TBT accepts f as size-preserving yet it is not.

@andreasabel
Copy link
Member Author

The use of with is (expectedly) also affected, you can swap f for this implementation:

f : U  U × ⊥
f u with u
... | u' = u' .force

@knisht
Copy link
Contributor

knisht commented Jun 15, 2024

Postmortem:
I had an optimisation where I did not record constraints of the form i ≤ ∞. Seems reasonable, but if i is a contravariant size variable, then the constraint should be reversed, and it starts making sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false Proof of the empty type which checks without known-unsafe flags (e.g. without --type-in-type) maculata Issue with a so far unreleased feature (not in changelog) type: bug Issues and pull requests about actual bugs type-based-termination Concerning `--type-based-termination`
Projects
None yet
Development

No branches or pull requests

2 participants