Use of Non-terminating Function in Data Declaration Makes Typechecker Loop
emekoi opened this issue · comments
The following causes Agda (agda --no-libraries Example.agda
) to go into an infinite loop.
data Unit : Set where
data Flip' (x : Unit) : (y : Unit) -> Set
Flip : Unit -> Unit -> Set
Flip x y = Flip y x
data Flip' a where
flip : Flip a a
I've attached the debug output at verbosity level 10 here. After a couple of seconds Agda stops producing output, but at verbosity level 999 (is there an upper limit? the manual doesn't say) when it starts looping it outputs the following:
E Semantics.Flip [] [E @0 [] [], E @0 [] []] []
M Semantics.Flip
[E @0 [] [], E @0 [] []]
done [x, y] (Semantics.Flip @0 @1)
[]
E (Semantics.Flip @0 @1) [@0 = E @0 [] [], @1 = E @0 [] []] [] []
This sounds somewhat similar to #2627 (specifically this comment.)
Agda version 2.6.4
Built with flags (cabal -f)
- enable-cluster-counting: unicode cluster counting in LaTeX backend using the ICU library
- optimise-heavily: extra optimizations
Yes, that's why we have a termination checker. But it does not run until the mutual block is complete. Your example opens an implicit mutual block with the data signature Flip'
which is only closed until the data definition Flip'
is provided.
Workaround is to use the {-# NON_TERMINATING #-}
pragma (insert before Flip
). This stops Flip
from being unfolded.
Ah, so this is the intended (unavoidable) behavior? Are definitions lifted out of mutual blocks if there isn't an actual dependency? Because the following terminates just fine:
data Unit : Set where
data Flip' (x : Unit) : (y : Unit) -> Set
Flip : Unit -> Unit -> Set
Flip x y = Flip y x
data Flip' a where
EDIT: Nevermind, we don't use Flip
here so when the termination checker runs, it doesn't get stuck trying to evaluate Flip
since it's never used.
Ah, so this is the intended (unavoidable) behavior?
Yes, somewhat unfortunately it is hard to fix:
Are definitions lifted out of mutual blocks if there isn't an actual dependency?
They formally stay in the mutual block, but the termination checker computes the actual dependencies.
Because the following terminates just fine:
Yes here you get the expected termination error for Flip
.
I am closing this as duplicate of #1270.